Unvalidated hardware frame length in RX path allows heap OOB read / uninitialized-memory info leak
Summary
In rum_bulk_read_callback mbuf reported length (m_pkthdr.len m_len) taken directly from 12-bit field in device-supplied RX descriptor ((flags>>16)&0xfff max 4095) without comparison against actual USB transfer length len or mbuf cluster capacity (MCLBYTES=2048). usbd_copy_out only writes len bytes (<=2048) into freshly-allocated non-zeroed cluster but mbuf advertises up to 4095 bytes. Subsequent readers (ieee80211_input radiotap/bpf listeners) walk offsets [len m_len) uninitialized cluster memory and offsets [MCLBYTES m_len) heap OOB read past cluster allocation. m_getcl returns non-zeroed cluster so stale kernel heap exposed. Both sibling Ralink drivers (if_mtw.c:2488 if_run.c:2783) close this exact hole. Attacker: malicious USB device presenting Ralink VID/PID. /dev/wlan0 monitor mode + bpf/tcpdump harvests leaked kernel heap bytes.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2356 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | gate analysis + unvalidated RX frame-len trace (siblings guard, rum does not) | 3.5 KB | β raw |
| fix.diff | suggested-fix | clamp mbuf len to min(dev_len, xfer_len, MCLBYTES) | 832 B | view raw |
| build.sh | build-script | documents HW gate | 157 B | view raw |
| run.sh | run-script | prints gate proof | 275 B | view raw |
| env.txt | environment | guest env | 1.1 KB | view raw |
| wifi_gate.txt | gate-proof | usbconfig empty, no wlan iface | 311 B | view raw |
DF-2356 β Unvalidated hardware frame length in RX (sys/bus/u4b/wlan/if_rum.c)
Verdict: NOT REPRODUCED (HW-gated); REAL BUG IN SOURCE (defense-in-depth fix warranted)
Hardware gate (why the PoC cannot run on this guest)
rum is the Ralink RT2501USB/RT2601USB 802.11bgn driver. It attaches only when
a matching Ralink USB wifi dongle (VID 0x148f / 0x0411 etc.) is plugged in. The
audit QEMU/KVM guest has no USB device and no wifi interface:
$ usbconfig list # No device match or lack of permissions. $ ifconfig -l # vtnet0 lo0 (no wlan/rum) $ pciconf -l | grep -iE "ralink|148f" # (no Ralink USB wifi chip) $ kldstat # kernel + ehci.ko + xhci.ko only
The RX path rum_bulk_read_callback runs only when the rum driver has
attached to a Ralink USB device and is receiving frames. With no such device the
path never executes. The unprivileged maxx user cannot plug a USB dongle into
the QEMU guest, and there is no adjacent rogue AP threat (no radio at all).
Source trace β the bug is REAL (sys/bus/u4b/wlan/if_rum.c)
In rum_bulk_read_callback (if_rum.c:1127-...):
usbd_xfer_status(xfer, &len, NULL, NULL, NULL); /* actual USB xfer len */
...
if (len < (int)(RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN)) goto tr_setup;
len -= RT2573_RX_DESC_SIZE; /* if_rum.c:1157 */
...
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); /* if_rum.c:1198, cluster=MCLBYTES=2048, NOT zeroed */
usbd_copy_out(pc, RT2573_RX_DESC_SIZE, mtod(m, uint8_t *), len); /* if_rum.c:1208 β bounded to <=2048 */
...
flags = le32toh(sc->sc_rx_desc.flags); /* device-controlled */
...
m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; /* if_rum.c:1221 β device-controlled 12-bit, max 4095 */
The descriptor's 12-bit length field ((flags >> 16) & 0xfff, range 0-4095) is
taken directly from the device RX descriptor and assigned to the mbuf's
m_len/m_pkthdr.len with no comparison against the actual USB transfer
length len or the cluster capacity MCLBYTES (2048). usbd_copy_out only
wrote len (β€ 2048) bytes into the non-zeroed cluster. Two consequences:
- Offsets
[len, m_len)(whenm_len > len) read uninitialised cluster memory β stale kernel heap exposed toieee80211_input, radiotap and bpf listeners (/dev/bpf*, monitor mode) β an info leak. - Offsets
[MCLBYTES, m_len)(whenm_len > 2048, possible since the field max is 4095) are a heap OOB read past the cluster allocation into adjacent slab objects.
Both sibling Ralink drivers close exactly this hole:
- if_mtw.c:2488 β if (__predict_false(len > dmalen - rxwisize)) goto fail;
- if_run.c:2783 β if (__predict_false(len > dmalen)) clamp.
Attacker: a malicious USB device presenting Ralink VID/PID, or a wireless
adjacent-network rogue AP sending crafted frames; /dev/wlan0 monitor mode +
bpf/tcpdump harvests leaked kernel heap bytes.
Exploit chain status
Not pursuable β primitive (heap OOB read / uninit info leak) requires a Ralink USB wifi dongle or adjacent radio (absent) β valid Phase-6 hard blocker: dead path at runtime on this guest. Read-only primitive; no escalation.
PoC changes
None. No Ralink USB wifi dongle on guest; verified by source trace only.
Recommended fix
Clamp the mbuf length to min(device_reported_len, len) (and to MCLBYTES),
matching the sibling drivers' guard. See fix.diff (matches finding proposal:
add the len > dmalen-style guard rum's siblings already have).
Fix verification
not_testablenot_testable: PoC cannot run on this guest (HW-gated, no target device). fix.diff validated by git apply --check (clean) + line-accurate source trace confirming it closes the cited path.
git apply --check findings/poc/DF-2356/fix.diff -> OK (clean apply). No runtime test possible (HW-gated).
Confirmed kernel references
Detail
Exploit chain
none β valid hard blocker (driver/device path dead at runtime on this guest: no target HW / no attached device). No unprivileged->root path.
Evidence (decisive lines)
usbconfig list -> No device match or lack of permissions.; pciconf -l -> no target controller HW; ifconfig -l -> vtnet0 lo0; kldstat -> kernel/ehci/xhci only; ls /dev/<target> -> No such file or directory; id maxx -> uid=1001 groups=1001 (not operator). Source confirmed at cited lines.
PoC changes
Created findings/poc/DF-2356/{VERDICT.md,fix.diff,build.sh,run.sh,env.txt,gate_proof.txt,manifest.json}. No PoC source (HW-gated).
Verified recommended fix
clamp device-reported length to len and MCLBYTES. Full git-apply-able diff in findings/poc/DF-2356/fix.diff (git apply --check OK).
Verdict
NOT REPRODUCED (HW-gated). The bug is REAL in source (traced line-by-line). rum unvalidated hardware frame length in RX (m_len device-controlled up to 4095 > MCLBYTES=2048 OOB read + uninit leak); no Ralink USB wifi. Gate confirmed via usbconfig list (No device match / no /dev/ugen*), pciconf -l (no target controller HW), ifconfig (vtnet0 lo0 only), kldstat (no target module), and ls /dev (no target nodes). maxx (uid 1001, not in operator) cannot reach any /dev/usbctl write path.
No comments yet.