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

urtwn_efuse_read_data writes past sc->rom union on malicious USB device (RTL8188EU extended efuse header)

Summary

urtwn_efuse_read_data() writes up to 8 attacker-supplied bytes at rom[off*8+0..7] without bounds-checking off against ROM buffer size. For RTL8188EU extended-header branch can synthesize off in [0 127] so writes land at indices up to 1023. sc->rom is union sized 512 bytes (size of r88e_rom) so any off>=64 writes past union into adjacent struct urtwn_softc fields: last_rom_addr sc_calib_to/sc_watchdog_ch callout structs (contain struct _callout *toc opaque pointer dereferenced by every callout operation) and sc_mtx lock. off=((reg2&0xf0)>>1)|(reg1>>5) spans 0..127 from device-controlled efuse bytes read via USB vendor request. Attacker: malicious USB device presenting RTL8188EU VID/PID auto-loads on plug-in. Overwrites callout toc pointer with controlled bytes. Impact: kernel panic DoS or local privilege escalation via callout pointer corruption.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2359 Β· 6 files
FileTypeDescriptionSize
VERDICT.md verdict gate analysis + efuse off>=64 write-past-rom trace 3.7 KB ↓ raw
fix.diff suggested-fix bounds-check off against URTWN_EFUSE_MAX_LEN/8 606 B view raw
build.sh build-script documents HW gate 162 B view raw
run.sh run-script prints gate proof 285 B view raw
env.txt environment guest env 1.1 KB view raw
wifi_gate.txt gate-proof usbconfig empty, no wlan iface 311 B view raw
VERDICT.md verdict gate analysis + efuse off>=64 write-past-rom trace
↓ download raw

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

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

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:

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:

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.

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

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

Verified recommended fix

reject off >= URTWN_EFUSE_MAX_LEN/8 at top of efuse_read_data. Full git-apply-able diff in findings/poc/DF-2359/fix.diff (git apply --check OK).

Verdict

NOT REPRODUCED (HW-gated). The bug is REAL in source (traced line-by-line). urtwn_efuse_read_data writes past sc->rom (off>=64 past 512-byte ROM into callout softc fields); no Realtek 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.