# DF-2359 — urtwn_efuse_read_data writes past sc->rom (sys/bus/u4b/wlan/if_urtwn.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)

`urtwn` is the Realtek RTL8188CU/RTL8188EU/RTL8188RU 802.11bgn USB wifi driver.
It attaches only when a matching Realtek USB wifi dongle 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/urtwn)
$ pciconf -l | grep -iE "realtek|0bda|2357"   # (no Realtek USB wifi chip)
$ kldstat                      # kernel + ehci.ko + xhci.ko only
```

The eFUSE read path (`urtwn_efuse_read` → `urtwn_efuse_read_data`) runs only at
attach time once a Realtek RTL8188EU/CU/RU 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 auto-triggers on attach from a malicious device's
eFUSE contents.

## Source trace — the bug is REAL (sys/bus/u4b/wlan/if_urtwn.c)

`sc->rom` is a union sized to the largest member (`if_urtwnvar.h:145-147,211`):
```c
union urtwn_rom { struct r92c_rom r92c_rom; struct r88e_rom r88e_rom; };
...
union urtwn_rom  rom;
```
`struct r88e_rom` (`if_urtwnreg.h:1028-1053`) is exactly 512 bytes
(`URTWN_EFUSE_MAX_LEN == 512`, `if_urtwnreg.h:1055`), and the read call for
RTL8188EU passes that size (`if_urtwn.c:1959`):
```c
error = urtwn_efuse_read(sc, (uint8_t *)rom, sizeof(sc->rom.r88e_rom));  /* 512 */
```

`urtwn_efuse_read_data` (`if_urtwn.c:1755-1781`) writes 8 bytes per `off` with
no bounds check on `off`:
```c
for (i = 0; i < 4; i++) {
    ...
    rom[off * 8 + i * 2 + 0] = reg;   /* if_urtwn.c:1770 */
    ...
    rom[off * 8 + i * 2 + 1] = reg;   /* if_urtwn.c:1777 */
}
```
`off` is computed in `urtwn_efuse_read` (`if_urtwn.c:1819-1836`) from
device-controlled eFUSE bytes:
```c
if ((sc->chip & URTWN_CHIP_88E) && (reg & 0x1f) == 0x0f) {   /* extended header */
    off = reg >> 5;
    URTWN_CHK(urtwn_efuse_read_next(sc, &reg));
    if ((reg & 0x0f) != 0x0f)
        off = ((reg & 0xf0) >> 1) | off;     /* if_urtwn.c:1827: off spans 0..127 */
    else
        continue;
} else
    off = reg >> 4;                            /* if_urtwn.c:1831 */
```
`off` can reach 127 (7 bits), so `off * 8 + 7` reaches index 1023 — but the
buffer is only 512 bytes (`URTWN_EFUSE_MAX_LEN`). For any `off >= 64`,
`off * 8 >= 512` writes **past `sc->rom`** into the adjacent `struct urtwn_softc`
fields: `last_rom_addr`, the `sc_calib_to` / `sc_watchdog_ch` callout structs
(whose `struct _callout *toc` opaque pointer is dereferenced by every callout
operation), and `sc_mtx`. A malicious RTL8188EU device synthesizes `off` in
`[64,127]` via crafted eFUSE bytes read through USB vendor requests, overwriting
the callout `toc` pointer with controlled bytes.

Impact: kernel panic / DoS, or local privilege escalation via callout-pointer
corruption. Trigger: malicious USB device presenting RTL8188EU VID/PID; auto-
loads on plug-in; no user interaction.

## Exploit chain status

Not pursuable — primitive (write past `sc->rom` into softc callout/lock fields)
requires the Realtek RTL8188EU device (absent) — valid Phase-6 hard blocker: dead
path at runtime on this guest. On hardware this is a write-capable softc-
corruption primitive.

## PoC changes

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

## Recommended fix

Bounds-check `off` against `URTWN_EFUSE_MAX_LEN / 8` before the write (skip the
entry if out of range). See `fix.diff` (matches finding proposal: validate `off`
in `urtwn_efuse_read_data` / its caller).
