STEPBY unsigned underflow via missing minimum length check (LMI_MIN_LENGTH defined never used) β ng7 twin of DF-0554
Summary
ng7 twin of DF-0554. LMI_MIN_LENGTH=8 defined(:88) never used. nglmi_checkdata reads fixed header bytes sequentially STEPBY(1)(:757/:783/:791/:806) without verifying packetlen>=1. packetlen u_short(:741). Short frame -> STEPBY underflows 0->0xFFFF -> IE loop while(packetlen>=2) iterates with huge packetlen -> data advances past mbuf into adjacent kernel heap. Hex-dump logging(:992-1046) exposes heap. Panics crossing unmapped page. Reliability depends on residual mbuf bytes matching expected values (0x03/0x7D/0x95). Fix: if(m_len<LMI_MIN_LENGTH) goto drop + packetlen>=1 guard before each STEPBY.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0562 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | full narrative: why not live, source-trace confirmation, twin-of-DF-0554 | 4.5 KB | β raw |
| fix.diff | suggested-fix | LMI_MIN_LENGTH guard at top of nglmi_checkdata (validated compile-only) | 715 B | view raw |
| build.log | build-log | ng7_lmi.ko standalone build, patched source, full output | 6.8 KB | view raw |
| env.txt | environment | guest uname, ng7 unshipped status | 928 B | view raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-0562 β ng7_lmi STEPBY underflow (twin of DF-0554)
Verdict
NOT REPRODUCED LIVE β but bug confirmed in source (latent in a parallel
source tree that is not built/shipped by default). The code is byte-for-byte
identical to the DF-0554 pattern in the shipped sys/netgraph/lmi/ng_lmi.c,
which I reproduced and patched live (see DF-0554 evidence pack).
Why not live-reproduced
sys/netgraph7/lmi/ng_lmi.c is built only when the kernel is compiled with
options NETGRAPH7 AND options NETGRAPH7_LMI (see
sys/conf/options:284,332 and sys/conf/files:1668+). The default
X86_64_GENERIC kernel ships the OLDER netgraph (sys/netgraph/lmi/ng_lmi.c)
as /boot/kernel/ng_lmi.ko. The two files have the same Makefile-target name
(ng_lmi.ko) so only one can be installed at a time; the audit guest ships
the older one (verified by strings /boot/kernel/ng_lmi.ko showing
/usr/src/sys/netgraph/lmi/ng_lmi.c).
Standalone make in /usr/src/sys/netgraph7/lmi does succeed (the file
itself is valid kernel C), but loading the resulting ng_lmi.ko would
require also loading the netgraph7 base (netgraph7/netgraph/ng_base.c),
which is not built/shipped either. Without an admin explicitly enabling
NETGRAPH7 in a custom kernel, the path is dead code.
Source-level confirmation (trace)
The bug pattern in sys/netgraph7/lmi/ng_lmi.c is identical to DF-0554:
| line | code | role |
|---|---|---|
:88 |
#define LMI_MIN_LENGTH 8 /* XXX verify */ |
defined, never used |
:544-548 |
STEPBY(stepsize) macro |
packetlen -= stepsize; data += stepsize; no guard |
:741 |
u_short packetlen; |
underflowable 16-bit unsigned |
:751 |
packetlen = m->m_len; |
init from mbuf length |
:757 |
STEPBY(1) after *data == 0x03 |
1st underflow site |
:783 |
STEPBY(1) after Protocol ID check |
2nd underflow site |
:791 |
STEPBY(1) after Call Ref check |
3rd underflow site |
:806 |
STEPBY(1) after msg-type switch |
4th underflow site |
:841 |
while (packetlen >= 2) IE loop |
iterates with wrapped packetlen=0xFFFF |
For a 1-2 byte mbuf, STEPBY(1) at :757 underflows packetlen from
0 to 0xFFFF (u_short). Subsequent *data reads at :760/:786/:794/:811
read past the mbuf into adjacent kernel heap. Same code path as DF-0554;
same effect (heap OOB read + leak via NGM_LMI_GET_STATUS).
Reachability on default install
not reachable β netgraph7 stack is opt-in and not shipped. If a future
release switches the default netgraph to netgraph7 (or an admin enables
NETGRAPH7_LMI), this bug becomes live. The fix is warranted as
defense-in-depth before that switch happens.
PoC
The DF-0554 PoC (df0554.c) triggers the bug on the shipped ng_lmi.ko
with the identical code pattern; the same PoC would trigger this finding
if ng7_lmi were loaded. See ../DF-0554/df0554.c and
../DF-0554/run.sh.
Recommended fix (validated compile-only)
fix.diff applies the same LMI_MIN_LENGTH guard to
sys/netgraph7/lmi/ng_lmi.c:751 (just after packetlen = m->m_len;,
before the first *data deref). Validated by:
patch -p4 < fix.diffβHunk #1 succeeded at 750.makein/usr/src/sys/netgraph7/lmiβ builds cleanly (/usr/obj/usr/src/sys/netgraph7/lmi/ng_lmi.ko, 15824 bytes).strings ng_lmi.ko | grep "too short"β the new log message is present.
Cannot run the PoC against this module on the audit guest because the
netgraph7 base is not shipped; the fix validation is therefore
not_testable (compile-only + traced close). The live behavior of an
identical patch on the shipped twin is documented in DF-0554 (status:
FIXED β baseline showed error at location -65533, patched shows
too short (N)).
Kernel references (verified by source trace)
sys/netgraph7/lmi/ng_lmi.c:88βLMI_MIN_LENGTHdefined, never used.sys/netgraph7/lmi/ng_lmi.c:544βSTEPBYmacro, no underflow guard.sys/netgraph7/lmi/ng_lmi.c:741βpacketlendeclaredu_short.sys/netgraph7/lmi/ng_lmi.c:751βpacketlen = m->m_len;.sys/netgraph7/lmi/ng_lmi.c:757,783,791,806β fourSTEPBY(1)sites.sys/netgraph7/lmi/ng_lmi.c:841β IE loopwhile (packetlen >= 2).sys/conf/options:284βNETGRAPH7opt-in.sys/conf/files:1668+β netgraph7 sources only built under NETGRAPH7_*.
Threat model
Same as DF-0554 (remote FR peer feeding crafted LMI over a serial link into an admin-configured ng_lmi node), but only on installations that opt into the netgraph7 stack. The bug is latent on default installs.
Fix verification
not_testablecompile validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. ng7_lmi STEPBY underflow (twin of DF-0554). netgraph7 not shipped. Compile validated.
No comments yet.