β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-0998

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-0998 Β· 7 files
FileTypeDescriptionSize
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
README.md readme summary
↓ download 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).

VERDICT.md verdict full narrative with arithmetic proof of the 16-byte overflow
↓ download raw

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_WR DMA 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 from MCLBYTES + RT2573_TX_DESC_SIZE to MCLBYTES
  • module_build.log β€” proof the patched if_rum.c compiles
  • VERDICT.md, README.md, manifest.json

Fix verification

not_testable

compile 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.