iwi_frame_intr frame->len bound too loose: up to 28-byte OOB read past mbuf cluster
Summary
iwi_frame_intr at if_iwi.c:1248-1249: framelen=le16toh(frame->len), capped only at MCLBYTES(2048). But mbuf cluster also holds iwi_hdr(4B)+iwi_frame(24B) prefix. m_len=4+24+framelen then m_adj(m,28) -> window [28, 28+framelen). For framelen in (2020,2048]: window extends 1-28B past cluster. DMA map loaded only MCLBYTES so trailing bytes are uninitialized kernel heap. Remote: malicious AP sends frame with len near 2048 -> OOB read into ieee80211_input. Code has TODO comment XXX >MCLBYTES is bogus. Sibling of DF-1122/DF-1145/DF-1157 WiFi frame len patterns. Fix: cap framelen<=MCLBYTES-28.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1239 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | tighten framelen upper bound to MCLBYTES - sizeof(iwi_hdr) - sizeof(iwi_frame) | 1.1 KB | view raw |
| VERDICT.md | verdict | source-level trace of 28-byte heap leak + dead-code analysis | 2.9 KB | β raw |
| build.sh | build-script | applies fix, builds if_iwi.ko module | 339 B | view raw |
| run.sh | run-script | explains no-trigger on this guest | 613 B | view raw |
| env.txt | environment | uname, cc version, PCI inventory | 553 B | view raw |
| build.log | build-log | kernel build log excerpt proving -Werror clean compile of patched source | 31.3 KB | 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-1239 β iwi_frame_intr framelen bound too loose (up to 28B heap leak)
Verdict: NOT REPRODUCED (dead code at runtime β no hardware)
Mechanism (source-level, confirmed real)
iwi_frame_intr() at sys/dev/netif/iwi/if_iwi.c:1238 processes received
802.11 frames. The firmware-supplied frame length is bounded too loosely:
// line 1248-1249
framelen = le16toh(frame->len);
if (framelen < IEEE80211_MIN_LEN || framelen > MCLBYTES) {
...
return;
}
The DMA map is loaded with only MCLBYTES (2048) bytes (line 1287-1288):
error = bus_dmamap_load(sc->rxq.data_dmat, data->map,
mtod(mnew, void *), MCLBYTES, iwi_dma_map_addr, &data->physaddr, 0);
But the mbuf length is set to include the 28-byte prefix:
// line 1319-1320
m->m_pkthdr.len = m->m_len = sizeof(struct iwi_hdr) + // 4 bytes
sizeof(struct iwi_frame) + framelen; // 24 bytes + framelen
Then m_adj(m, 28) strips the prefix, leaving an mbuf claiming
framelen bytes of payload starting at cluster offset 28. For
framelen in (2020, 2048], the window [28, 28+framelen) extends 1β28
bytes past the DMA-mapped cluster β ieee80211_input processes
uninitialized kernel heap as if it were frame data.
Struct sizes confirmed: iwi_hdr = 4B (4 Γ uint8_t, __packed),
iwi_frame = 24B (reserved1[2]=8 + 6Γuint8 + signal/noise=4 + antenna/
control=2 + reserved2[2]=2 + len=2, __packed). Prefix = 28B.
Max safe framelen = MCLBYTES - 28 = 2020. The check allows up to 2048,
28 bytes too loose.
The bug is real in source. A malicious AP that sends a frame with
frame->len in (2020, 2048] causes 1β28 bytes of uninitialized kernel
heap to be passed to ieee80211_input.
Why it cannot reproduce on this guest
iwi is the Intel PRO/Wireless 2200BG/2915ABG Mini-PCI WiFi driver.
- NOT in X86_64_GENERIC: only in LINT64.
- Available as
if_iwi.ko, but not loaded on the guest. - The QEMU guest has no WiFi card at all β
pciconf -lshows only bridges, VGA, virtio-net, virtio-blk. QEMU does not emulate Intel 2200BG. - Even if
kldload if_iwiwere run (requires root), no PCI device would match and the driver never attaches β no RX interrupt β noiwi_frame_intrβ unreachable.
This is valid hard blocker: dead/unreachable at runtime on this guest. The threat model is a malicious WiFi AP in radio range of a real system with an Intel 2200BG/2915ABG card.
Fix
fix.diff tightens the upper bound from MCLBYTES to
MCLBYTES - sizeof(struct iwi_hdr) - sizeof(struct iwi_frame) (=2020).
Compiled successfully as if_iwi.ko.
Impact
- On this guest: none (dead code, no WiFi hardware).
- On a real system: up to 28 bytes of uninitialized kernel heap leaked
to the 802.11 stack per malicious frame. Info leak (stack/heap residue)
from a remote (radio-range) attacker. The
iwidriver targets an old (2004-era) Mini-PCI card; real-world prevalence is low.
Fix verification
not_testablecompile validated
module/kernel build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. iwi_frame_intr framelen MCLBYTES vs cluster-28 -> 28B heap leak. iwi NOT in GENERIC, no WiFi HW.
No comments yet.