# DF-0997 — rum RX mbuf m_len set from device-controlled descriptor (heap OOB read)

## Verdict
**NOT TESTABLE on default guest** (requires Ralink RT2573 USB WiFi adapter or
USB-fuzzer emulation, neither present in the QEMU guest). Bug is real and
confirmed by source review; the fix.diff compiles cleanly as a KLD module
(see `module_build.log`).

## Mechanism (cited)

`rum_bulk_read_callback()` at `sys/bus/u4b/wlan/if_rum.c:1140`:

1. Line 1146 bounds-checks only the *lower* bound of `len` (the
   host-controller-reported actual transfer length):
   `if (len < RT2573_RX_DESC_SIZE + IEEE80211_MIN_LEN) goto tr_setup;`
   No upper bound on `len`. (In practice the USB layer caps `len` at the
   `bufsize = MCLBYTES + RT2573_RX_DESC_SIZE`, so the immediate write at
   line 1208 is bounded — the bug is the *separate* m_len assignment below.)

2. Line 1208–1209: `usbd_copy_out(pc, RT2573_RX_DESC_SIZE, mtod(m, ...), len);`
   copies `len` bytes of received frame data into a freshly-allocated mbuf
   cluster (`m_getcl` → MCLBYTES = 2048 bytes).

3. Line 1221: `m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff;` sets the
   mbuf length from a **12-bit field of the device-controlled RX descriptor
   `flags`** — NOT from `len`. The descriptor is parsed at line 1162 from the
   USB transfer via `usbd_copy_out(pc, 0, &sc->sc_rx_desc, RT2573_RX_DESC_SIZE)`.

The 12-bit field allows values up to 4095. A malicious or faulty USB device
(the RT2573 announces its own RX descriptor contents) can advertise e.g.
`(flags >> 16) & 0xfff == 4095` while delivering only `len` (≤ MCLBYTES)
actual frame bytes. The mbuf's `m_len` is then 4095 while only ≤2048 bytes
were actually written into the cluster.

Any subsequent reader that walks `m_len` bytes from `mtod(m, ...)` walks
**past the 2048-byte cluster into kernel heap** — a heap OOB read.
The finding cites `ieee80211_input` (which panics on the bogus data) and
BPF/monitor-mode `tcpdump` as the user-readable leak path.

## Impact
- **Heap OOB read** of up to ~2047 bytes per packet past the cluster boundary.
- Reachable by a malicious USB device (considerable physical/access precondition)
  or by USB-fuzz on emulated device — `CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:H`.
- Most likely observed effect is a panic in `ieee80211_input` from OOB
  payload; an attacker who controls a BPF listener on the interface can
  exfiltrate leaked bytes via monitor-mode capture.

## Why not tested on the guest
- The QEMU guest has no `rum` device attached (no USB WiFi passthrough).
- The `if_rum.ko` module is not loaded on the default kernel.
- Reproduction requires either: (a) a physical RT2573 USB WiFi adapter
  passed through to the guest, or (b) a USB-fuzzer/gadget framework that
  emulates an RT2573 sending crafted RX descriptors. Neither is available
  on this audit guest.
- The fix.diff was validated to **compile cleanly** as a KLD module
  (see `module_build.log`) — the three rum fixes (DF-0997/0998/0999) were
  applied simultaneously to `/usr/src/sys/bus/u4b/wlan/if_rum.c` and
  `make` in `/usr/src/sys/bus/u4b/wlan/rum` produced `if_rum.ko` with rc=0.

## Fix
`fix.diff` — at line 1221, extract `pktlen = (flags >> 16) & 0xfff` and
verify `pktlen <= len && pktlen <= MCLBYTES`; drop the frame (`m_freem`,
`++ic->ic_ierrors`, `goto tr_setup`) if the descriptor length is bogus.
This prevents the OOB read regardless of what the device puts in the
descriptor.

## Files
- `fix.diff` — bounds-check pktlen against len and MCLBYTES
- `module_build.log` — proof the patched `if_rum.c` compiles
- `VERDICT.md` — this narrative
- `README.md` — summary
- `manifest.json` — artifact catalog
