DF-5254 / verdict.json
{ "finding_id": "DF-5254", "status": "inconclusive", "reproduced": false, "impact": "none", "confidence": "likely", "verdict": "Use-after-free WRITE on struct urtwn_vap.bcn_mbuf: urtwn_update_beacon() releases sc_mtx around ieee80211_beacon_update() (if_urtwn.c:2206-2212, writer holds only the net80211 com lock via iv_update_beacon callers such as ieee80211_set_tim) while urtwn_setup_beacon() frees-and-swaps the same mbuf under sc_mtx with the com lock dropped (urtwn_newstate if_urtwn.c:2551-2552, setup at 2168-2171; IBSS S_RUN re-entry is remotely triggerable via ieee80211_ibss_merge->ieee80211_sta_join1), and urtwn_vap_delete() frees it with no lock at all (840-841). No lock orders writer against freer. On-guest kernel PoC is hardware-gated (no RTL8188 USB NIC on the QEMU guest; if_urtwn.ko present but unloadable without a device), so kernel-level reproduction is honestly recorded as inconclusive; a faithful three-thread two-lock-domain simulation of the exact interleaving reproduced the write-after-free in 6/6 runs on the guest as an unprivileged user, including the vap_delete variant (run.2.log). Severity High (memcorrupt), twin of the if_run.c pass-2 beacon-lifecycle family.", "exploit_chain": "unauthenticated remote peer (IBSS) or local admin-triggered state churn -> (1) attacker sends crafted beacons with larger TSF to force ieee80211_ibss_merge -> newstate(S_RUN) re-entry -> urtwn_setup_beacon m_freem(bcn_mbuf) under sc_mtx; concurrently (2) station power-save traffic drives ieee80211_set_tim -> urtwn_update_beacon -> ieee80211_beacon_update writes TIM/CSA bytes into the freed 2KB mbuf cluster -> cross-object heap corruption (cluster pool recycles immediately) -> crash today, controlled-content write into recycled kernel object with pool grooming. Simulated chain proven at interleaving level (exit=3, 6/6); hardware chain not exercised.", "evidence": "race_sim.c + run.log (5/5 runs exit=3 UAF write detected, gens 220/184/186/404/403), run.2.log (vap_delete variant, C frees=1), VERDICT.md source trace with path:line for all three racing paths, fix.diff (git apply --check clean)", "kernel_refs": [ "sys/bus/u4b/wlan/if_urtwn.c:2206", "sys/bus/u4b/wlan/if_urtwn.c:2212", "sys/bus/u4b/wlan/if_urtwn.c:2168", "sys/bus/u4b/wlan/if_urtwn.c:2171", "sys/bus/u4b/wlan/if_urtwn.c:2551", "sys/bus/u4b/wlan/if_urtwn.c:840", "sys/netproto/802_11/wlan/ieee80211_power.c:316", "sys/netproto/802_11/wlan/ieee80211_node.c:630" ], "poc_changes": "No kernel PoC possible (hardware-gated); built race_sim.c from scratch: pthread model of the exact lock choreography (com held across update path, sc dropped at 2206, com dropped at 2551, no-lock vap_delete), zone-allocator emulation with generation counters so a stale-generation write is a true write-after-free. Iterations: fixed aligned_alloc size-misuse crash, made vap_delete thread leave the field dangling (as the kernel does) instead of NULLing it.", "attempts": 4, "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": 95, "guest_dirty": 0, "build_cmd": "cc -O2 -pthread -Wall -o race_sim race_sim.c", "run_cmd": "./race_sim 5 (x5 runs, exit code 3 == UAF write detected)", "code_hash": "37a2eb97099454f50001c3b36f6cb3611f259b8021e76d627552980257d8f5a3", "notes": "Hardware-gated: guest has if_urtwn.ko in /boot/kernel but no RTL8188/8192 USB device (kldstat empty for urtwn, usbdevs empty). Requires a urtwn-supported NIC in hostap or ibss mode on real hardware to fire in-kernel; in IBSS the racing S_RUN re-entry is drivable by an unauthenticated peer. Simulated evidence per protocol for hardware-gated findings.", "recommended_fix": "Hold URTWN_LOCK(sc) across ieee80211_beacon_update() in urtwn_update_beacon() and take URTWN_LOCK(sc) around m_freem(uvp->bcn_mbuf) in urtwn_vap_delete() (see fix.diff)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff is git-apply-able against sys/ and removes the unlocked window by construction (B/C serialize on sc_mtx with the writer); kernel build+device test not possible on this guest (no USB WLAN hardware) so not_testable", "fix_evidence": "findings/poc/DF-5254/fix.diff (git apply --check PASSED); locking argument in VERDICT.md" } |