# DF-3638 — ath_tx_retry_clone() error path leaks the node reference and recycles a buffer with dangling bf_m

## What

`sys/dev/netif/ath/ath/if_ath_tx.c:4567-4583` — when the DMA-map reload of a
cloned retry/filtered frame fails, the clone `nbf` is pushed back onto the
free list while still owning the *moved* `bf_node` reference (never
decref'd) and a `bf_m` pointer that dangles at the mbuf chain freed inside
`ath_tx_dmasetup()`.

## Chain (source-level, machine-verified)

- `ath_tx_retry_clone()` is called for BUSY buffers during software retry of
  aggregate subframes (`ath_tx_retry_subframe`, if_ath_tx.c:4723) and
  filtered-frame handling (`ath_tx_tid_filt_comp_single`, if_ath_tx.c:3495).
- `ath_buf_clone()` (if_ath.c:3170) moves `bf_m`/`bf_node` into `nbf`
  (ownership transfer; original NULLed).
- `ath_tx_dmasetup(sc, nbf, nbf->bf_m)` fails (bus_dmamap_load NOWAIT
  ENOMEM / linearize failure under memory pressure) — the mbuf is freed
  *inside* dmasetup (if_ath_tx.c:320/338/349/356).
- Error path returns `nbf` to `sc->sc_txbuf` **without** decref'ing
  `nbf->bf_node` or clearing `nbf->bf_m` (if_ath_tx.c:4579-4581).
- `_ath_getbuf_locked()` (if_ath.c:3080) does not clear `bf_m`/`bf_node`
  on reuse → next consumer inherits the stale fields until a successful
  reload overwrites them.

## Impact

- Permanent leak of one ieee80211_node + ath_node (≈ KBs each, incl. 17
  TIDs, BAW tracking, rate state) per occurrence → slow station-slot/memory
  exhaustion (DoS) on hosts with ath(4) hardware under memory pressure.
- Latent use-after-free pointer field in a recycled kernel buffer (not
  dereferenced along current call graphs, but one refactor away from a real
  UAF; `ath_tx_freebuf()`'s `bus_dmamap_unload` on `bf->bf_m != NULL` is
  the nearest would-be sink).

## Reachability

ath(4) interface + a bus_dmamap_load NOWAIT failure during retry-clone.
Guest has no Atheros hardware (see env.txt) — runtime reproduction
impossible; `verify_df3638.py` proves the control flow (8/8 PASS).

## Files

verify_df3638.py (the PoC), run.sh, run.log, env.txt, VERDICT.md,
fix.diff, verdict.json, manifest.json.
