DF-5258 / verdict.json
{ "finding_id": "DF-5258", "status": "inconclusive", "reproduced": false, "impact": "none", "confidence": "certain", "verdict": "Structurally proven in-kernel: the DragonFly if_mtwvar.h:323 declares sc_epq[MTW_BULK_RX] where MTW_BULK_RX is the first enum constant (== 0) - a zero-length array - while FreeBSD upstream declares sc_epq[MTW_EP_QUEUES] (cgit.freebsd.org sys/dev/usb/wlan/if_mtwvar.h). sizeof(struct mtw_softc)=28928 therefore EXCLUDES the queues, yet mtw_init_locked() (if_mtw.c:4466-4467) calls mtw_setup_tx_list() on sc->sc_epq[0..5] on every interface UP, memset-stamping 6x2344=14064 bytes starting at softc offset 12032. A kld module built against the guests real kernel headers printed the exact alias map (probe_run.log): the stamp region overlays live softc fields - txpow*/lna/rssi (TX-power EEPROM tables wiped -> device transmits at zeroed power), and critically sc_chan_group @+12300 lands INSIDE epq[0].tx_data[3].ni (@+12296..12304, +52 = upper 4 bytes of the node pointer): every channel change (mtw_set_chan, if_mtw.c:3758) rewrites the top 32 bits of a live ieee80211_node pointer with 0..3. An idle entry then carries forged ni=0x200000000 into mtw_unsetup_tx_list->ieee80211_free_node (detach) or an in-flight entry carries 0x0000000N_xxxxxxxx into ieee80211_tx_complete() (mtw_tx_free, if_mtw.c:2769) - a wild/forged node pointer, userspace-mappable in the 0xN00000000 range, dereferenced and written (refcount decrement). cmd_seq @+12304 and sc_detached @+12305 alias desc[] of the same entry. Live-kernel trigger needs an MT7601U dongle + ifconfig wlanX up (commonly auto-done by network managers), so the in-kernel impact is hardware-gated on this QEMU guest; the structure, sizes, offsets and stamping were all verified in-kernel with the real headers.", "exploit_chain": "plug MT7601U -> ifconfig wlan create/UP -> 14KB stamp over live tail fields -> channel change writes 0..3 into top dword of epq[0].tx_data[3].ni -> idle: ieee80211_free_node(0x200000000) at next detach/down teardown (wild write); in-flight: ieee80211_tx_complete on 0xNxxxxxxxx forged node -> panic, or with cmd_seq (<=0xFF) as byte 4 and an mmapd user page at that address, refcount write / node_free on fully attacker-crafted node -> privesc plausible", "evidence": "probe_run.log (in-kernel, real if_mtwvar.h md5 0a8f339bbc49064bc903215a1c21063f): sizeof(sc->sc_epq) as declared = 0, sc_chan_group @+12300 INSIDE epq[0] tx_data[3] +52 (ni) ; mtwprobe.c; VERDICT.md alias table", "kernel_refs": [ "sys/bus/u4b/wlan/if_mtwvar.h:323", "sys/bus/u4b/wlan/if_mtwvar.h:251", "sys/bus/u4b/wlan/if_mtw.c:4466", "sys/bus/u4b/wlan/if_mtw.c:949", "sys/bus/u4b/wlan/if_mtw.c:3758", "sys/bus/u4b/wlan/if_mtw.c:2769", "sys/bus/u4b/wlan/if_mtw.c:985" ], "poc_changes": "Probe module written from scratch; includes the verbatim mtw_setup_tx_list() and the real if_mtwvar.h from the guest /usr/src", "attempts": 3, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 140, "guest_dirty": 0, "build_cmd": "cd /tmp/mtwp && make SYSDIR=/usr/src/sys NO_WERROR=1 (module; needs opt_*.h/device_if.h/bus_if.h from /usr/obj kernel dir)", "run_cmd": "kldload /tmp/mtwprobe.ko && dmesg | grep mtwprobe:", "code_hash": "12144b3945339529f95b5c6683d9309f8be9d93941e2ec01d14a557956fba5b5", "notes": "All mtw(4) paths are hardware-gated on the QEMU guest (no USB controller is passed through and no MT7601U device model exists); evidence is in-kernel structural (DF-5258: kld probe against the real if_mtwvar.h) or userland interleaving simulation mirroring the exact code regions/lock domains, per the wlan-trio pass-2 methodology (cf. DF-5246..DF-5257).", "recommended_fix": "Size the array correctly: sc_epq[MTW_EP_QUEUES] (matches FreeBSD upstream)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff authored and verified with git apply --check against the pristine sys/ tree, but cannot be kernel-tested: the guest has no USB controller and no MT7601U device model, so neither baseline nor patched kernel behavior is exercisable. Hardware-gated: not_testable.", "fix_evidence": "fix.diff (git-apply clean); VERDICT.md" } |