DF-4620 / verdict.json
{ "finding_id": "DF-4620", "status": "reproduced", "reproduced": 1, "impact": "dos", "confidence": "certain", "verdict": "REPRODUCED on the DragonFly guest (verbatim-extraction harness, mode 2): with an EEPROM-shaped zero-gain dataset (xpd_mask=0 -> all numVpd=0, the exact shape ar2413SetupRawDataset produces) the functions backfill loops index with uint32 counters at 0: pPdGainBoundaries[ii-1] (ar5413.c:528) and pPDADCValues[kk-1] (:532) wrap to element index 0xFFFFFFFF and read at array+0x1FFFFFFFE bytes (+8.59 GB) \u2014 proven by SIGSEGV si_addr exactly equal to gb+0x1FFFFFFFE (0xa004902c2) in the fault flavor, and by mapping the exact wild pages (kernel direct-map emulation) and observing both 0x5A5A values propagate into gainBoundaries[0] (-> AR_PHY_TPCRG5) and pcdacTable[0] (-> 32 PHY reg writes). Plus uninitialized-stack read of Pmin_t2[0] at :468 (minPower varies run-to-run: 0xd320/0xd370/0xd300). In-kernel this is a wild KVA read -> panic (KVA hole) or garbage radio programming; HALASSERT(:580) is compiled out in release. Fix validated (early return): no wild reads, no uninit read.", "exploit_chain": "crafted EEPROM xpd_mask=0 -> numPdGainsUsed==0 at ar5413.c:463 -> :528/:532 uint32 index wrap reads at +0x1FFFFFFFE from kernel-stack array and kernel-heap pcdacTable -> value programmed to AR_PHY_TPCRG5 / replicated to pdadc table + PHY regs; :468 uninit stack read -> ah_txPowerIndexOffset. Panic-or-garbage; no exfil channel, no uid0 route (hardware-gated).", "evidence": "run.log mode 2 lines: gainBoundaries[0] = 0x5a5a, pcdacTable[0] = 0x5a5a, minPower out = 0xd320, DF-4620 REPRODUCED: uint32-underflow wild reads at ar5413.c:528/:532 + uninit stack read at :468; fix_run.log: patched mode 2 shows 0x0000/0xaaaa/0x7c7c (untouched).", "kernel_refs": [ "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:429", "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:468", "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:527", "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:528", "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:531", "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:532", "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:580", "sys/dev/netif/ath/ath_hal/ar5212/ar5413.c:639", "sys/dev/netif/ath/ath_hal/ah_eeprom_v3.c:643", "sys/dev/netif/ath/ath_hal/ah_internal.h:665" ], "poc_changes": "no seed PoC; mode 2 of the shared verbatim-extraction harness: wild pages mmapd at the exact wrapped addresses with 0x5A5A to emulate kernel direct-map survival (fault flavor also captured: si_addr == gb+0x1FFFFFFFE exact); gainBoundaries passed via a heap struct whose pre-array bytes carry a marker", "attempts": 3, "guest_uname": "DragonFly dfbsd 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": 90, "guest_dirty": 0, "build_cmd": "sh build.sh (verbatim extraction of ar5413.c:288-540 + cc -O2)", "run_cmd": "./ar5413_harness 2", "code_hash": "fc8693ed15ae1678c4d1a170d2a138dd392f5a59d49cadbaab442826f4a371c1", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0 x86_64 (harness-level validation of patched function bodies; kernel-build validation hardware-gated)", "fix_verdict": "fix.diff returns early when numPdGainsUsed==0 and makes ar5413SetPowerTable fail; patched run shows no wild-read propagation (0x0000/0xaaaa) and minPower sentinel 0x7c7c preserved (the :468 uninit read never executes).", "fix_evidence": "fix_run.log --- mode 2 section: gainBoundaries[0]=0x0000, pcdacTable[0]=0xaaaa, minPower=0x7c7c", "notes": "Same uint32-underflow class also occurs at :508-509 on a different trigger (flat curves) \u2014 filed as DF-4622; distinct root cause and guard from known DF-1766 (numChannels==0).", "recommended_fix": "Early-return when numPdGainsUsed==0 before the Pmin_t2[0] read and backfill loops; fail ar5413SetPowerTable on 0 gains (see fix.diff)." } |