{
  "finding_id": "DF-3638",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "Source-level confirmed (8/8 machine-checked assertions, run.log): when the DMA reload of a cloned retry/filtered frame fails, ath_tx_retry_clone() (sys/dev/netif/ath/ath/if_ath_tx.c:4567-4583) recycles nbf via ath_returnbuf_head() without dropping the node reference moved into it by ath_buf_clone() (if_ath.c:3186-3187, 3212-3213) and without clearing nbf->bf_m, which dangles at the mbuf chain freed inside ath_tx_dmasetup() (if_ath_tx.c:320/338/349). _ath_getbuf_locked() (if_ath.c:3080) does not sanitize bf_m/bf_node on reuse, so the recycled buffer carries the stale pointers. Net effect: one ieee80211_node/ath_node leaked per occurrence (slow station/memory exhaustion DoS on ath(4) hosts under memory pressure) plus a latent UAF pointer field one refactor away from a real use-after-free. Runtime reproduction impossible on the hardware-less guest (env.txt): honest not_reproduced; impact none reflects the run, not the ceiling.",
  "exploit_chain": "",
  "evidence": "findings/poc/DF-3638/run.log (8/8 PASS: clone ownership move at if_ath.c:3170+, error-path recycling without decref/mbuf-detach at if_ath_tx.c:4571-4585, _ath_getbuf_locked not clearing bf_m/bf_node); VERDICT.md; env.txt.",
  "kernel_refs": [
    "sys/dev/netif/ath/ath/if_ath_tx.c:4540",
    "sys/dev/netif/ath/ath/if_ath_tx.c:4568",
    "sys/dev/netif/ath/ath/if_ath_tx.c:4579",
    "sys/dev/netif/ath/ath/if_ath_tx.c:294",
    "sys/dev/netif/ath/ath/if_ath_tx.c:4723",
    "sys/dev/netif/ath/ath/if_ath_tx.c:3495",
    "sys/dev/netif/ath/ath/if_ath.c:3170",
    "sys/dev/netif/ath/ath/if_ath.c:3080",
    "sys/dev/netif/ath/ath/if_ath.c:4844"
  ],
  "poc_changes": "No seeded PoC; authored verify_df3638.py (source-level artifact) - hardware-gated defect.",
  "attempts": 1,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 30,
  "guest_dirty": 0,
  "build_cmd": "python3 findings/poc/DF-3638/verify_df3638.py (static analysis of read-only sys/ tree)",
  "run_cmd": "sh findings/poc/DF-3638/run.sh",
  "code_hash": "71783994aef2e33da842d73d98c8c082484683c4e1d59cc7bc20642e7f062c3c",
  "notes": "Pass-2 (GLM 5.3) audit of if_ath_tx.c. Upstream-inherited (FreeBSD same path). Severity Low: node-ref leak + latent dangling pointer; trigger needs ath hardware + busdmamap NOWAIT failure during retry-clone of a BUSY aggregate/filtered frame.",
  "recommended_fix": "In ath_tx_retry_clone()s dmasetup-error path, ieee80211_node_decref(nbf->bf_node) and NULL bf_m/bf_node before ath_returnbuf_head(); harden _ath_getbuf_locked() to clear bf_m/bf_node on reuse.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff detaches node/mbuf on the error path and clears bf_m/bf_node in _ath_getbuf_locked (defense in depth matching the ath_freebuf KASSERT contract); cannot be runtime-validated without ath hardware.",
  "fix_evidence": "findings/poc/DF-3638/fix.diff (two hunks); run.log assertions 3, 5, 7 identify exactly the lines patched."
}