# DF-3282 — ieee80211_beacon_update: NULL `bo->bo_appie` pointer arithmetic writes app IE to near-NULL kernel address (panic)

File: `sys/netproto/802_11/wlan/ieee80211_output.c` (pass 2 audit)

## What

`ieee80211_beacon_construct()` (line 3215-3219) records
`bo->bo_appie`/`bo->bo_appie_len` **only when `vap->iv_appie_beacon != NULL`
at beacon-construction time**. If a beacon application IE is installed
*later* (SIOCS80211 `IEEE80211_IOC_APPIE` with subtype BEACON — exactly what
hostapd does when WPS is enabled/disabled on a running AP, or when any
app IE blob is pushed after the AP came up), `ieee80211_beacon_update()`'s
APPIE block (lines 3591-3613) computes

```c
int adjust = aielen - bo->bo_appie_len;   /* 0 -> 64 */
bcopy(bo->bo_tim_trailer, bo->bo_tim_trailer+adjust, bo->bo_tim_trailer_len);
bo->bo_tim_trailer += adjust;
bo->bo_appie += adjust;                    /* NULL + 64 == 0x40 */
...
frm = add_appie(bo->bo_appie, aie);        /* memcpy to 0x40 */
```

`bo->bo_appie` is NULL (never set), so the IE is memcpy'd to kernel
address `0x0+ie_len` — a guaranteed fatal page fault on every
execution. Reproduced on the stock INVARIANTS guest:

```
fw: wlan0 RUN, beacon allocated          <- beacon built with no app IE
setting 64-byte beacon app IE on wlan0... (SIOCS80211 APPIE, root)
Fatal trap 12: page fault while in kernel mode
fault virtual address	= 0x40
fault code		= supervisor write data, page not present
Stopped at      memcpy+0x1c:    movq    %rdx,(%rdi)
```

## Build / run (repo root)

```
sh findings/poc/DF-3282/build.sh     # builds /root/fw/fw.ko + setappie in guest
sh findings/poc/DF-3282/run.sh       # baseline: panics within ~100ms of ioctl
```

The harness (`fw.c`) is a minimal software net80211 radio: registers an
`ieee80211com` ("fw0") with hostap support, allocates the beacon via
`ieee80211_beacon_alloc()` on RUN and services `ieee80211_beacon_update()`
from a 100 ms callout — the same discipline as a real MAC driver at TBTT.

## Expected output

Baseline (stock kernel): `panic`/fatal trap 12, fault VA = ie_len (0x40),
guest down (see `panic.txt`).

Patched (fix.diff applied, kernel rebuilt): ioctl succeeds, beacon keeps
updating (dmesg shows continued beacon ticks, `ifconfig wlan0 destroy`
works, guest stays up). See `VERDICT.md`.

## Threat

Privileged local DoS (SIOCS80211 requires SYSCAP_NONET_WIFI). Reachable
through the standard hostapd/WPS beacon-IE plumbing on any running AP
whose beacon predates the first app IE — the common ordering.
