{
  "finding_id": "DF-5032",
  "status": "untested",
  "verdict": "Bounds defect is certain: ar5212InvalidGainReadback (ar5212_rfgain.c:140) extracts gStep via ar5212GetRfField(bank7, 6, 37, 0), whose byte walk (ar5212_rfgain.c:102-117) reads rfBuf[4] and rfBuf[5], but the RF bank-7 shadow arrays of the 2413/2316/2317/5413/2425/2417 backends have only 3 words (ar5212.ini:1870,1878,1886,2158,2166; only 5111 has 8, 5112 has 13 and takes the other branch). Kernel-path execution was not possible: the probe is armed only on 5 GHz channels (ar5212_reset.c:1085-1094; driver polls ath_hal_getrfgain, if_ath.c:5401) and the audit guest has no Atheros hardware. Impact on the reachable path (ar5413, 5 GHz): the 8 bytes land in vpdTable_L inside the same ath_hal_mallocd priv struct (ar5413.c:35-57) - C-level array OOB / UB, no heap violation, value never exported nor used as an index - so the practical effect is miscalculated loTrig/hiTrig (ar5212_rfgain.c:143-149) and misfiring gain-ladder adjustments: RF performance degradation only. Dormant variant: ar2425/2417 where Bank7Data is the final struct member (ar2425.c:36-45) would make the same read an 8-byte heap OOB read, gated off because those radios are 2.4 GHz-only. Severity Low; verification skipped per contract (hardware-only trigger). The index-walk arithmetic demo (oob_demo.c, byte-for-byte replica of the walk) ran on the DragonFly guest and prints the OOB for all five 3-row radios (oob_demo.log, exit 1).",
  "reproduced": false,
  "impact": "none",
  "confidence": "certain",
  "exploit_chain": "",
  "evidence": "oob_demo.log: InvalidGainReadback/else GetRfField(bank7, 6, 37, 0) words touched: [4] [5] (max index 5) followed by ar5413 (else path) N(ar5212Bank7_5413) = 3 rows -> index 5 *** OUT OF BOUNDS (reads 2 words past) *** (x5 radios), exit 1; static refs ar5212_rfgain.c:140 + ar5212.ini bank7 row counts",
  "kernel_refs": [
    "sys/dev/netif/ath/ath_hal/ar5212/ar5212_rfgain.c:140",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5212_rfgain.c:102",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5212.ini:1870",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5212.ini:1886",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5212.ini:2166",
    "sys/dev/netif/ath/ath_hal/ar5212/ar2425.c:36",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:35",
    "sys/dev/netif/ath/ath_hal/ar5212/ar5212_reset.c:1090"
  ],
  "poc_changes": "No prior PoC; oob_demo.c authored this pass (pure-arithmetic replica of ar5212GetRfFields index walk vs the real bank-7 row counts).",
  "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": 15,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o oob_demo oob_demo.c",
  "run_cmd": "sh run.sh",
  "code_hash": "2a11dde5e4855d2994a7ae2fb5291f04ccec912a46a88e006338fc879384de25",
  "notes": "Verification skipped per contract (Low severity, hardware-only trigger; no ath device on guest). Guest scratch cleaned.",
  "recommended_fix": "Size Bank7Data[] >= 6 words in the 2413/2316/2317/5413/2425/2417 RF priv structs (keeps the generic byte-walk in bounds), or restrict the gStep extraction at ar5212_rfgain.c:140 to radios whose bank-7 layout actually holds bits 33-43 (RF5111).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "Fix validation not applicable: memory-corruption reproduction did not occur (no hardware), and the finding is Low severity / functional RF impact only.",
  "fix_evidence": "n/a"
}