# 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`):
```c
sc->txd_fw = (struct mtw_txd_fw *)kmalloc(MTW_MAX_TXSZ, ...);
```
where (`if_mtw.c:128-129`)
```c
#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`):
```c
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`):
```c
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.

## Recommended fix

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