# DF-5292 — rum beacon mbuf write-after-free across disjoint lock domains

## What
`rum_update_beacon()` (sys/bus/u4b/wlan/if_rum.c:2792-2831) drops `RUM_LOCK`
at :2825 and then calls `ieee80211_beacon_update(ni, m, mcast)` at :2828,
which WRITES seqno/capinfo/TIM/ERP element data into `rvp->bcn_mbuf`'s 2 KB
cluster while holding only the net80211 ic lock
(net80211/wlan/ieee80211_output.c:3339 ff.).  Two other paths free or
replace that same cluster under disjoint lock domains:

 * `rum_newstate()` — releases `IEEE80211_LOCK(ic)` at :932, takes
   `RUM_LOCK(sc)` at :933, and on S_RUN `rum_alloc_beacon()` (:977 → :2775-2778)
   does `m_freem(rvp->bcn_mbuf)` + replace, holding only the sc lock.
 * `rum_vap_delete()` — `m_freem(rvp->bcn_mbuf)` at :715 with NO lock at all.

ic-lock vs sc-lock are disjoint ⇒ a free landing between :2825 and the end of
the in-mbuf writes is a kernel write-after-free on a freed 2 KB cluster.

Twin of DF-5246 (if_run), DF-5254 (if_urtwn), DF-5259 (if_mtw).

## Hardware gating
All rum(4) paths need an RT2501/RT2601 USB dongle to attach; the QEMU guest
has none, so in-kernel reproduction is not possible.  Evidence is (a) the
line-level lock-domain trace above and (b) a userland interleaving model of
the exact code regions and locks (`rum_beacon_race.c`), run 3×10 s on the
guest.  The struct/module `if_rum.ko` was kldload'ed on the guest to confirm
the audited code is the running build (md5-identical source tree).

## Build / Run / Expected
```
cc -O2 -pthread -Wall -o rum_beacon_race rum_beacon_race.c
./rum_beacon_race 10        # 3 runs
```
Expected: `freed-in-window UAF WRITES` > 0 in every run (reachability of the
interleave); see `run.log` (1, 9, 3 hits in the first series; 5, 2, 13 in the
preemption-mode series — the userspace floor; the in-kernel window is
microseconds of TIM/element recompute and is unbounded under preemption).

## Fix
`fix.diff` — hold `RUM_LOCK` across the beacon_update in-mbuf writes (and take
it around the `m_freem` in `rum_vap_delete`).  `git apply --check` clean.
Kernel fix validation is hardware-gated (`fix_status: not_testable`).
