β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-0562

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0562 Β· 6 files
FileTypeDescriptionSize
VERDICT.md verdict full narrative: why not live, source-trace confirmation, twin-of-DF-0554 4.9 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
VERDICT.md verdict full narrative: why not live, source-trace confirmation, twin-of-DF-0554
↓ download 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.

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:

  1. patch -p4 < fix.diff β†’ Hunk #1 succeeded at 750.
  2. make in /usr/src/sys/netgraph7/lmi β†’ builds cleanly (/usr/obj/usr/src/sys/netgraph7/lmi/ng_lmi.ko, 15824 bytes).
  3. 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)

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 status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable

compile 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.