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

txd_fw buffer overflow on firmware load: 6 KB heap overflow + kernel-memory leak to USB device on every attach

Summary

sc->txd_fw allocated at only MTW_MAX_TXSZ=sizeof(mtw_txd)+sizeof(mtw_txwi)+MCLBYTES+11=2083 bytes but mtw_ucode_write copies firmware in 0x2000=8192-byte chunks into txd_fw->buf. Stock mtw7601ufw firmware has ilm_len=0xb144 so first chunk does memcpy(txd_fw->buf fw 8192) into 2079-byte usable buffer - 6113-byte heap overflow on every device attach. mtw_fw_callback then sets up USB DMA of data->len+8=8200 bytes from same 2083-byte allocation so 6117 bytes of adjacent kernel heap read out and transmitted to USB device (info leak). Triggered automatically whenever mtw driver attaches to MT7601U device at boot or hot-plug. No privileges no user interaction required. Two impacts: (a) kernel heap corruption 6113 bytes adjacent slab overwritten with firmware bytes attacker-controlled via malicious USB device (b) kernel memory info leak ~6KB adjacent heap to USB device.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2354 Β· 6 files
FileTypeDescriptionSize
VERDICT.md verdict gate analysis + txd_fw 6KB heap overflow + info-leak trace 3.6 KB ↓ raw
fix.diff suggested-fix size txd_fw to hold a full 0x2000 firmware chunk 627 B view raw
build.sh build-script documents HW gate 161 B view raw
run.sh run-script prints gate proof 260 B view raw
env.txt environment guest env 1.1 KB view raw
wifi_gate.txt gate-proof usbconfig empty, no wlan iface, no wifi modules 311 B view raw
VERDICT.md verdict gate analysis + txd_fw 6KB heap overflow + info-leak trace
↓ download raw

DF-2354 β€” txd_fw buffer overflow on firmware load (sys/bus/u4b/wlan/if_mtw.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)

mtw is the MediaTek MT7601U (and MT7610U/MT7612U) USB 802.11bgn driver. It attaches only when a matching USB wifi dongle (VID 0x148f PID 0x7601 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/mtw)
$ pciconf -l | grep -iE "ralink|mediatek|148f|14c3"   # (no USB wifi chip)
$ kldstat                      # only kernel + ehci.ko + xhci.ko (no if_mtw module loaded)

The firmware-load path (mtw_loadmicrocode β†’ mtw_ucode_write) runs at attach time once an MT7601U device is present. With no such device the path never executes; the unprivileged maxx user cannot plug a USB dongle into the QEMU guest. The bug also auto-triggers on every attach (no user interaction), but only on hardware that owns the device.

Source trace β€” the bug is REAL (sys/bus/u4b/wlan/if_mtw.c)

sc->txd_fw allocation (if_mtw.c:548):

sc->txd_fw = (struct mtw_txd_fw *)kmalloc(MTW_MAX_TXSZ, ...);

where (if_mtw.c:128-129)

#define MTW_MAX_TXSZ (sizeof(struct mtw_txd) + sizeof(struct mtw_txwi) + MCLBYTES + 11)

β‰ˆ 2083 bytes total (MCLBYTES = 2048). struct mtw_txd_fw (if_mtwvar.h:74-78) is { uint16_t len; uint16_t flags; uint8_t buf[]; }, so buf has β‰ˆ 2079 usable bytes.

Firmware chunk copy (mtw_ucode_write, if_mtw.c:1063-1077):

blksz = 0x2000;                          /* 8192 bytes */
...
xferlen = min(len - sent, blksz);        /* up to 8192 */
txd = sc->txd_fw;
txd->len   = htole16(xferlen);
txd->flags = htole16(MTW_TXD_DATA | MTW_TXD_MCU);
memcpy(txd->buf, fw + sent, xferlen);    /* if_mtw.c:1077 β€” writes up to 8192
                                          * bytes into a ~2079-byte buffer */
memset(txd->buf + xferlen, 0, MTW_DMA_PAD);

Stock MT7601U firmware (mtw7601ufw) has ilm_len = 0xb144, so the first chunk is a full 8192-byte memcpy into the 2079-byte buf β€” a ~6113-byte heap overflow of sc->txd_fw into the adjacent slab on every device attach.

Worse, the USB transmit completion (mtw_fw_callback, if_mtw.c:2908-2925):

struct mtw_txd_fw *data = sc->txd_fw;
...
case USB_ST_SETUP:
    len = data->len + sizeof(struct mtw_txd) + MTW_DMA_PAD;   /* β‰ˆ 8192+ */
    usbd_xfer_set_frame_len(xfer, 0, len);

submits a USB DMA of data->len + headers β‰ˆ 8200 bytes from the same 2083-byte allocation β€” reading ~6 KB of adjacent kernel heap out and transmitting it to the USB device (kernel-memory info leak to a malicious device).

Two impacts: (a) ~6 KB heap overwrite with firmware bytes (attacker-controlled via a malicious USB device's firmware), (b) ~6 KB adjacent kernel heap leaked to the USB device. Triggered automatically on attach; no privilege/user interaction.

Exploit chain status

Not pursuable β€” primitive (large heap overflow + info leak on attach) requires the MT7601U device (absent) β€” valid Phase-6 hard blocker: dead path at runtime on this guest. On hardware this is a write-capable heap-corruption primitive.

PoC changes

None. No MT7601U USB wifi dongle on guest; verified by source trace only.

Size txd_fw to hold a full firmware chunk (round MTW_MAX_TXSZ up, or allocate a dedicated MTW_FW_BUFSIZE >= 0x2000 + headers for the firmware-load buffer). See fix.diff (matches finding proposal intent: bound the firmware buffer to the chunk size actually copied).

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

not_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-2354/fix.diff -> OK (clean apply). No runtime test possible (HW-gated).
↓ fix.diffn/a (no target HW/device on this guest)

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-2354/{VERDICT.md,fix.diff,build.sh,run.sh,env.txt,gate_proof.txt,manifest.json}. No PoC source (HW-gated).

Verified recommended fix

size txd_fw to sizeof(struct mtw_txd_fw)+0x2000+MTW_DMA_PAD. Full git-apply-able diff in findings/poc/DF-2354/fix.diff (git apply --check OK).

Verdict

NOT REPRODUCED (HW-gated). The bug is REAL in source (traced line-by-line). mtw txd_fw buffer overflow on firmware load (~6KB heap overflow per attach); no MT7601U 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.