TX DMA buffer overflow: mbuf length clamp uses wrong bound -> 16-byte heap overwrite past USB DMA buffer
Summary
rum_config[RUM_BULK_WR].bufsize=2080 (MCLBYTES+RT2573_TX_DESC_SIZE+8=2080) at if_rum.c:438. rum_bulk_write_callback :1057 clamps m_pkthdr.len to MCLBYTES+RT2573_TX_DESC_SIZE=2072. But TX desc at offset 0 is separate; mbuf payload at offset 24. 2072 bytes at offset 24 = end 2096 > 2080 buffer -> 16-byte overwrite past DMA buffer. :1063 desc at offset 0, :1064 m_copy_in at offset RT2573_TX_DESC_SIZE=24. usbd_get_page returns (usb_size_t)-1 so no USB-layer catch. Trigger: BPF raw injection via ic_raw_xmit (CAP_NET_RAW) or high MTU (>2025). Fix: clamp to MCLBYTES not MCLBYTES+TX_DESC_SIZE.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-0998 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | clamp m_pkthdr.len to MCLBYTES (not MCLBYTES + RT2573_TX_DESC_SIZE) | 1020 B | view raw |
| module_build.log | build-log | if_rum.ko compiles cleanly with the fix applied | 1.3 KB | view raw |
| VERDICT.md | verdict | full narrative with arithmetic proof of the 16-byte overflow | 2.9 KB | β raw |
| README.md | readme | summary | 717 B | β raw |
| manifest.json | manifest | this catalog | 2.2 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-0998 β rum TX DMA buffer 16-byte overwrite
Summary
rum_bulk_write_callback at sys/bus/u4b/wlan/if_rum.c:1057-1065 clamps
m->m_pkthdr.len to MCLBYTES + RT2573_TX_DESC_SIZE = 2072, then writes
the mbuf payload at offset RT2573_TX_DESC_SIZE = 24. End offset =
24 + 2072 = 2096, but the DMA buffer is only 2080 bytes β 16-byte
overwrite.
Why not tested on default guest
No RT2573 USB adapter on the QEMU guest. if_rum.ko is not loaded.
Trigger requires USB HW or USB-gadget emulation.
Fix
fix.diff changes the clamp to MCLBYTES (the correct upper bound for
the mbuf payload portion of the buffer).
Compilation check
Compiles cleanly into if_rum.ko (see module_build.log).
DF-0998 β rum TX DMA buffer 16-byte overwrite
Verdict
NOT TESTABLE on default guest (requires Ralink RT2573 USB WiFi adapter,
not present). Bug is real and confirmed by arithmetic review of the
descriptor/buffer layout; the fix.diff compiles cleanly as a KLD module
(see module_build.log).
Mechanism (cited)
rum_config[RUM_BULK_WR].bufsize = MCLBYTES + RT2573_TX_DESC_SIZE + 8
= 2048 + 24 + 8 = 2080 bytes (sys/bus/u4b/wlan/if_rum.c:438).
rum_bulk_write_callback() at sys/bus/u4b/wlan/if_rum.c:1028:
1057: if (m->m_pkthdr.len > (int)(MCLBYTES + RT2573_TX_DESC_SIZE)) {
1058: DPRINTFN(0, "data overflow, %u bytes\n", m->m_pkthdr.len);
1060: m->m_pkthdr.len = (MCLBYTES + RT2573_TX_DESC_SIZE); /* 2072 */
1061: }
1062: pc = usbd_xfer_get_frame(xfer, 0);
1063: usbd_copy_in(pc, 0, &data->desc, RT2573_TX_DESC_SIZE); /* TX desc at offset 0 (24 B) */
1064: usbd_m_copy_in(pc, RT2573_TX_DESC_SIZE, m, 0, m->m_pkthdr.len); /* payload at offset 24 */
The TX descriptor is written at offset 0 (24 bytes). The mbuf payload
is written starting at offset 24. The clamp at line 1057 allows
m->m_pkthdr.len up to MCLBYTES + RT2573_TX_DESC_SIZE = 2072.
End offset of the mbuf write = 24 + 2072 = 2096, but the buffer is only 2080 bytes. That is a 16-byte overwrite past the DMA buffer.
usbd_get_page returns (usb_size_t)-1 for the residual, so the USB layer
does not catch the overflow.
Trigger path
The finding cites BPF raw injection via ic_raw_xmit (which a user with
CAP_NET_RAW or root can drive) or a high-MTU frame (>2025 bytes payload)
as the way to produce an mbuf with m_pkthdr.len large enough to hit the
overflow.
Impact
- Heap overwrite of 16 bytes past the
RUM_BULK_WRDMA buffer. - Adjacent slab/heap object corruption; with grooming, potentially
exploitable for privilege escalation (typical kmalloc-4096 or page
bucket β exact bucket depends on the USB host-controller buffer
allocator, which is in
sys/bus/u4b/). CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:H(Medium as filed).
Why not tested on the guest
Same as DF-0997: no rum USB device on the QEMU guest. The if_rum.ko
module is not loaded. Reproduction requires USB HW or a USB-gadget fuzzer.
Fix
fix.diff β clamp m->m_pkthdr.len to MCLBYTES (not
MCLBYTES + RT2573_TX_DESC_SIZE). Then end-offset = 24 + 2048 = 2072 β€
2080, comfortably inside the buffer (with 8 bytes of headroom for the
end-alignment padding at line 1082: len = (RT2573_TX_DESC_SIZE +
m->m_pkthdr.len + 3) & ~3; if ((len % 64) == 0) len += 4;).
Compilation check
Fix (applied with DF-0997 and DF-0999) compiles cleanly into if_rum.ko.
See module_build.log.
Files
fix.diffβ change clamp fromMCLBYTES + RT2573_TX_DESC_SIZEtoMCLBYTESmodule_build.logβ proof the patchedif_rum.ccompilesVERDICT.md,README.md,manifest.json
Fix verification
not_testablecompile validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. rum TX DMA 16B overflow (clamp MCLBYTES+DESC vs bufsize). No if_rum HW. Fix compiles.
No comments yet.