# DF-3437 — wlan scan dispatchers run `ss_ops->…` without the com lock, racing `ieee80211_scan_vdetach`'s `scan_detach` which frees `ss->ss_priv`

`sys/netproto/802_11/wlan/ieee80211_scan.c` dispatches through
`ss->ss_ops` **without** `IEEE80211_LOCK` in:

- `ieee80211_scan_timeout` (:582-588) — called from the
  `ieee80211_node_timeout` **callout**, which takes no com lock
  (`ieee80211_node.c:2243-2256`);
- `ieee80211_scan_iterate` (:626-633) and `ieee80211_scan_flush`
  (:639-647).

The teardown side, `ieee80211_scan_vdetach` (:137-155), *does* hold the
lock and calls `ss->ss_ops->scan_detach(ss)` → `sta_detach`
(`ieee80211_scan_sta.c:186-199`) which **kfrees `ss->ss_priv`** (the whole
`sta_table`) and never clears `ss->ss_priv`; `ss->ss_ops = NULL` happens
only afterwards in vdetach. Interleaving:

```
callout:  if (ss->ss_ops != NULL)      /* unlocked read - true  */
vdetach:  (lock) scan_detach(ss) -> sta_detach: kfree(ss->ss_priv)
vdetach:  ss->ss_ops = NULL; (unlock)
callout:  ss->ss_ops->scan_age(ss)     /* stale ops; sta_age derefs
                                          the freed ss_priv under
                                          SCAN_TABLE_LOCK(st) on freed
                                          memory */
```

`scan_age` (`ieee80211_scan_sta.c`) immediately does
`st = ss->ss_priv; IEEE80211_SCAN_TABLE_LOCK(st); TAILQ_...` — lock
acquire and list walk on freed memory. Trigger:
`ifconfig wlanX destroy` (root) racing the per-com inactivity timer.
UAF → panic/corruption; root-gated trigger, tiny window, but the
pattern is a real TOCTOU on an unlocked function-pointer dispatch
(the DF-0587 family — same lock-discipline hole, different site).

## Verification status

**untested** — the guest has no 802.11 radio device and DF has no virtual
802.11 driver, so a vap cannot be created (`ifconfig wlan0 create wlandev
…` requires a parent radio). The 802.11 pass-1 findings with the same
constraint (DF-0640, DF-0587) were left unverified for the same reason.
Code walk above is the evidence; fix is to take `IEEE80211_LOCK(ic)`
around the unlocked dispatchers (or make `sta_detach` clear `ss->ss_priv`
and the readers re-validate under the lock).
