# DF-3968 verdict — certain NULL-check gap, race-gated DoS

## Reproduced?
No Ralink NIC on the audit guest (env.txt), so the destroy-vs-scan race could
not be exercised. Source-level certainty is high:

- rt2661.c:2843-2847: `vap = TAILQ_FIRST(&ic->ic_vaps); ... rt2661_set_bssid(
  sc, vap->iv_bss->ni_bssid);` — no NULL check.
- rt2661.c:2747-2750 (enable_tsf_sync): `vap = TAILQ_FIRST(...); if
  (vap->iv_opmode != ...)` — no NULL check; reached from scan_end and from
  the RUN transition (newstate, which always has a vap).
- Call site: ieee80211_scan_sw.c:781-797 — scan_end() drops the COM lock
  before `ic->ic_scan_end(ic)` and re-acquires after, explicitly warning
  that scan state can change during the driver call.
- Tear side: ieee80211_scan.c:140-155 — ieee80211_scan_vdetach(vap) (under
  IEEE80211_LOCK, from ieee80211_vap_delete) clears ss_vap and the vap leaves
  ic_vaps; nothing re-validates the driver's TAILQ_FIRST snapshot.

⇒ `ifconfig wlanX destroy` racing a completing background scan on the last
vap dereferences NULL → panic (local DoS; destroy is privileged).

## Fix
fix.diff adds NULL guards at both sites (two-line defense).

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
