# DF-5293 VERDICT — deferred cmdq entry executes rum_set_beacon on a freed rum_vap

**Status: inconclusive (hardware-gated).  Bug: real, line-proven.**

## Reproduction path (in-kernel)

1. Attach rum(4), create hostap/ibss `wlan0`, bring up (S_RUN; beacon
   exists).
2. Trigger `iv_update_beacon` (TIM churn from a power-save client, ERP
   change, ioctl): `rum_update_beacon` queues `&vap` into `cmdq[]` and
   `ieee80211_runtask(cmdq_task)` (:2830, :768).
3. Before the taskqueue thread executes `cmdq_task` (backlogged queue, or
   plain scheduling latency), destroy the vap:
   `ifconfig wlan0 destroy` → `rum_vap_delete` → `kfree(rvp)` (:720).
   Nothing drains `sc->cmdq_task` and nothing purges the entry.
4. Taskqueue runs `rum_update_beacon_cb` → `rum_set_beacon(sc, vap)`:
   - :2733 `m = rvp->bcn_mbuf` — read of freed `rum_vap`
     (also the mbuf itself was freed at :715)
   - :2744 `vap->iv_txparms[...]` — read of freed `rum_vap`
   - :2754-2755 `rum_write_multi(..., mtod(m), m->m_pkthdr.len)` — wild
     kernel read with freed-heap-controlled length, streamed to the device.
   Freed `rum_vap` slots are immediately reusable (any vap create / other
   M_80211_VAP allocations), so the callback operates on reallocated memory
   → garbage pointers → panic-capable.

## Why inconclusive on this guest
No RT2573 hardware; rum(4) never attaches; the cmdq/vap lifecycle cannot be
entered.  Structural evidence only (source md5-identical, module loads).

## Simulated evidence
`rum_cmdq_uaf.c` models the 16-slot ring, producers storing the raw pointer,
a taskqueue worker with dispatch latency, and the destroyer running
`rum_vap_delete` with (mode 0) and without (mode 1) the missing drain.
Guest results (3×10 s each): shipped mode → 11599/11849/12071 post-free
`rum_set_beacon` executions (~61 % of callbacks); drained mode → 0/0/0.
The destroyer's free-window and the worker latency are modeled timings; the
structural claim (no drain ⇒ queued entry can outlive the vap) is exact.

## Divergences from the twins (checked, NOT affected)
- cmdq ring locking: rum producers take RUM_CMDQ_LOCK (:753-766) — the
  torn-publish bug of DF-5249/DF-5262 does NOT apply.
- key deferral: `rum_key_set`/`rum_key_delete` copy `sizeof(*k)` BY VALUE
  (:3021/:3038) — the raw-key UAF of DF-5250/DF-5263 does NOT apply.
- The vap pointer at :2830 is the single dangling deferred reference.

## Exploit chain (if hardware present)
post-free `rum_vap` reallocation (heap groom of M_80211_VAP zone) →
`rum_set_beacon` reads attacker-shaped `bcn_mbuf` → `rum_write_multi`
streams `m_pkthdr.len` bytes from an attacker-shaped pointer to the device
(info disclosure over the air in hostap mode) plus wild kernel read →
panic; primarily a UAF-driven DoS/disclosure primitive.

## Fix
`ieee80211_draintask(ic, &sc->cmdq_task)` in `rum_vap_delete()` before
`kfree(rvp)` (fix.diff, `git apply --check` clean).  Overlaps the DF-5292
fix in `rum_vap_delete` (trivial merge).  Kernel fix validation is
hardware-gated: not_testable.

## Kernel references
- sys/bus/u4b/wlan/if_rum.c:2830 (raw &vap queued)
- sys/bus/u4b/wlan/if_rum.c:745-771 (rum_cmd_sleepable: async runtask)
- sys/bus/u4b/wlan/if_rum.c:723-743 (rum_cmdq_cb drains ring)
- sys/bus/u4b/wlan/if_rum.c:2784-2790 (cb derefs data->vap)
- sys/bus/u4b/wlan/if_rum.c:2729-2755 (rum_set_beacon on vap/bcn_mbuf)
- sys/bus/u4b/wlan/if_rum.c:709-721 (vap_delete: no cmdq drain; kfree :720)

## 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.
