# DF-5247 — pending `run_cmdq` entries outlive the vap/node they point at

`sys/bus/u4b/wlan/if_run.c`

## What

`run_update_beacon()` (4894-4898), `run_key_set()` (2368-2375),
`run_bulk_tx_callbackN()` timeout path (3157-3161) and `run_newassoc()`
(2669-2675) stash **raw `vap` / `ieee80211_node` pointers** in
`sc->cmdq[i]` and defer execution via `ieee80211_runtask()`.

When a vap is destroyed (`ifconfig wlanX destroy` →
`wlan_clone_destroy` → `run_vap_delete`, ieee80211_dragonfly.c:125-131),
`run_vap_delete()` frees the beacon mbuf and `kfree(rvp, M_80211_VAP)`
(if_run.c:1013, 1030). `ieee80211_vap_detach()` drains **only**
`iv_nstate_task` and `iv_swbmiss_task`
(sys/netproto/802_11/wlan/ieee80211.c:775-778) — it never drains the
driver's `sc->cmdq_task` / `sc->ratectl_task`. Those are drained only in
`run_detach()` (if_run.c:879-880), i.e. when the whole USB device goes
away.

A still-pending cmdq entry then executes after the free:
`run_update_beacon_cb(vap)` dereferences the freed `run_vap`
(4904-4952), `run_key_set_cb` dereferences the freed vap
(`cmdq->arg1 = vap`, 2237-2256), `run_newassoc_cb` dereferences a
possibly-freed node (2625-2639) — kernel use-after-free read/write.

## Simulated reproduction

`vap_lifetime.c` models the exact ordering (queue → free → reuse →
deferred callback runs). Output on the guest:

    run_update_beacon_cb: vap=0x800490ac0 beacon_mbuf=0x0 (already freed: yes)
    UAF observed: deferred callback dereferenced freed run_vap

The dynamic in-kernel repro needs a real run(4) adapter (beacon/key
activity) — hardware-gated on this QEMU guest → status `inconclusive`,
confidence `likely`.
