# DF-0712 — reproduce

## Build
```
./build.sh        # cc -O2 -Wall -o harness harness.c
```

## Run
```
./run.sh          # ./harness
```

## Expected (bug present — unpatched `#0` kernel's logic)
The harness replicates `ieee80211_alloc_countryie` (`sys/netproto/802_11/wlan/ieee80211_regdomain.c:248-326`)
with a canary-guarded allocation. With 84 channel power-runs (the `IEEE80211_COUNTRY_MAX_BANDS`
cap), it reports a **3-byte heap OOB write** past the 257-byte allocation:
```
  OOB+1: alloc[257] = 0x01   # #channels, constant
  OOB+2: alloc[258] = <ic_maxregpower>   # ATTACKER-CONTROLLED byte
  OOB+3: alloc[259] = 0x00   # odd-length IE pad byte, constant
RESULT: 3-byte heap OOB write detected past the 257-byte allocation.
```

## Why a harness (not a live in-kernel PoC)
The live `ieee80211_alloc_countryie` path requires a WiFi radio (it is called while
assembling a hostap beacon). This audit guest has **no WiFi hardware** (`ifconfig -l` ⇒
`vtnet0 lo0`; no `wlan`/`80211` modules), so the path is unreachable at runtime. The
harness replicates the exact allocation + IE-assembly logic byte-for-byte and proves the
off-by-3 deterministically.

## After the fix (`harness_fixed.c`, alloc = 260 bytes)
```
RESULT: no overflow detected (bug not present).
```

## Notes
- On the default GENERIC slab allocator, `kmalloc(257)` rounds up to a **288-byte**
  bucket (31 bytes of intra-object tail padding), so the 3 overflow bytes land in
  padding — no *adjacent* object is corrupted and there is no panic. The bug is a real
  correctness/defense-in-depth defect; it would be a true cross-object corruption on a
  tighter allocator. See `VERDICT.md` for the full impact analysis.
- `SIOCS80211` (the ioctl to set the channel/regdomain trigger) is root-gated
  (`caps_priv_check_self(SYSCAP_NONET_WIFI)`, `ieee80211_ioctl.c:3472`), so there is no
  unprivileged path to the sink even with WiFi hardware.
