DF-4661 / verdict.json
{ "finding_id": "DF-4661", "status": "reproduced", "reproduced": 1, "impact": "dos", "confidence": "certain", "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": 3, "guest_dirty": 0, "build_cmd": "cd /root/df2413 && sh build.sh", "code_hash": "649368a4f0ba8c2b3e06ce44e4570d0ca199c48de7f40bd49afefb09bcc22a81", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Validated on the guest: fixA+B+C applied to a copy of the pristine ar2413.c, function bodies re-extracted verbatim from the patched copy, harness rebuilt and re-run. Baseline reproduces the defect; patched build shows the defect GONE (mode 1: no overflow / mode 2: early return, sentinel minPower, no wild-read propagation / mode 3: completes without the wild-address SIGSEGV). fix.diff is git-apply-able against the pristine tree (git apply --check clean) and was never applied to sys/.", "fix_evidence": "fix_run.log (full patched 3-mode run) vs run.log (baseline); fix.diff in pack; PATCHES_APPLIED + FIXED_BUILD_OK in fix_run.log.", "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 at ah_eeprom_v3.c:656-673) the functions backfill loops index with uint32 counters at 0: pPdGainBoundaries[ii-1] (ar2413.c:484) and pPDADCValues[kk-1] (ar2413.c:488) wrap to element index 0xFFFFFFFF and read at array+0x1FFFFFFFE bytes (+8.59 GB) -- the direct-map survival case proven by mapping the exact wild pages and observing both 0x5A5A values propagate into gainBoundaries[0] (-> AR_PHY_TPCRG5 by ar2413SetPowerTable:595-600) and pcdacTable[0] (-> 32 PHY reg writes, ar2413.c:586-593); the identical wrap arithmetic proven to fault in mode 3 (SIGSEGV si_addr == expected wild address). Plus uninitialized-stack read of Pmin_t2[0] at ar2413.c:424 (minPower varies run-to-run: 0xd2e0/0xd3b0/0xd620/0xd370). In-kernel this is a wild KVA read -> panic (KVA hole) or garbage radio programming; HALASSERT(:536) is compiled out in release and the caller (:533-535) never checks the return. Twin of DF-4620 (ar5413) / DF-4649 (ar2316). Fix validated (early return + caller check): no wild reads, no uninit read.", "exploit_chain": "crafted v3 EEPROM (xpd_mask=0) on AR2413 card -> numPdGainsUsed==0 -> uint32-wrapped wild reads at gb+0x1FFFFFFFE and pcdacTable+0x1FFFFFFFE (direct-map garbage or KVA-hole panic) + uninit Pmin_t2[0] stack read -> garbage TPCRG5/pdadc programming or kernel panic. No uid0 route.", "evidence": "run.log mode 2: gainBoundaries[0] = 0x5a5a, pcdacTable[0] = 0x5a5a, DF-4661 REPRODUCED; repeat section: minPower 0xd3b0/0xd620/0xd370 (uninit variance); fix_run.log patched mode 2: ret=0, sentinel minPower 0x7c7c, no propagation.", "kernel_refs": [ "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:424", "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:484", "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:488", "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:533", "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:536", "sys/dev/netif/ath/ath_hal/ar5212/ar2413.c:579", "sys/dev/netif/ath/ath_hal/ah_eeprom_v3.c:656", "sys/dev/netif/ath/ath_hal/ah_internal.h:665" ], "poc_changes": "Same harness as DF-4660 (mode 2); no kernel-code changes.", "notes": "Same uint32-underflow class also occurs at ar2413.c:464-465 on a different trigger (flat curves) -- filed as DF-4662; distinct root cause and guard from known DF-1796 (numChannels==0, pass 1, NOT re-reported).", "recommended_fix": "Early-return 0 when numPdGainsUsed==0 before the Pmin_t2[0] read, plus a caller-side numPdGainsUsed==0 -> AH_FALSE check in ar2413SetPowerTable (fix.diff).", "run_cmd": "./ar2413_harness 2", "attempts": 1 } |