Missing minimum-length check + u_short packetlen underflow in LMI packet parser kernel heap OOB read
Summary
LMI_MIN_LENGTH=8 defined(:88) but never used. Neither nglmi_rcvdata nor nglmi_checkdata enforces minimum packet length. Loop variable packetlen is u_short while STEPBY macro(:544-548) does unchecked packetlen-=step. 0-4 byte mbuf surviving byte-by-byte header checks causes packetlen wrap from 0 to 65535 then IE-parsing loop while(packetlen>=2) walks data far past mbuf storage into adjacent kernel heap. m_pullup check :576 dead (m_len<packetlen identically false). STEPBY(1) at :757/:783/:791/:806 consume bytes past valid. Per-iteration reads data[0]/data[1] become silent OOB reads ~85 iterations past MHLEN~172. No info leak logs bounded m_len no controlled write. [VERIFIED pass2: reproduced - 4-byte Annex-D frame checkdata errors at location -65528 proving 8 bytes walked past after packetlen wrapped 0 to 65535; LMI_MIN_LENGTH guard proposed]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2603 Β· 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| harness.c | β | 4.7 KB | view raw | |
| build.sh | β | 89 B | view raw | |
| run.log | β | 973 B | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
lmi run + dmesg: error at location -65528 for the 4-byte frame vs location 8 for the 8-byte control
PoC changes
real ng_lmi.c checkdata + crafted cluster with controlled residue
Verified recommended fix
enforce LMI_MIN_LENGTH (m_len >= 8) at the top of nglmi_checkdata/nglmi_rcvdata
Verdict
LMI_MIN_LENGTH=8 (ng_lmi.c:88) is never enforced and STEPBY() decrements u_short packetlen unchecked. Real ng_lmi.c (compiled into the harness, linkage-only edits): a 4-byte Annex-D frame [03 09 00 7D] drove nglmi_checkdata into nglmi: unexpected SEQ ... error at location -65528 -- the parsers OWN error dump shows the data pointer 8 bytes past the packet after packetlen wrapped 0->65535 and the IE loop consumed residue beyond m_len (the 0x95 locking shift + IE stream read from stale cluster bytes). Control 8-byte frame errored at location 8 (in-bounds). Bytes feed parser decisions only (no return path), matching the findings no-leak/no-write assessment; a sufficiently long garbage walk could still fault into unmapped memory (DoS ceiling).
No comments yet.