DF-4682 / verdict.json
{ "finding_id": "DF-4682", "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/df2317 && sh build.sh", "run_cmd": "./ar2317_harness 3", "code_hash": "2a6f1714d2a77176c8c164e7a8ea4dd9153f22a3bdecb466c9af8ded31a0d901", "verdict": "REPRODUCED on the DragonFly guest (verbatim-extraction harness, mode 3): with 4 pdGains whose EEPROM power curves are FLAT (all pwr_t4 deltas zero -> Pmax_t2 == Pmin_t2), sizeCurrVpdTable = Pmax_t2[ii] - Pmin_t2[ii] (ar2317.c:438, uint32 arithmetic of int16 values) is 0, and the Vpd_step computation at ar2317.c:445-446 reads VpdTable_I[ii][sizeCurrVpdTable-1] and [sizeCurrVpdTable-2] -- element indices 0xFFFFFFFF and 0xFFFFFFFE under uint32 arithmetic -- i.e. wild reads at row+0x1FFFFFFFE bytes (+8.59 GB). Left unmapped, the harness faulted with SIGSEGV si_addr == &vpdTable_I[0][0] + 0x1FFFFFFFE exactly (asserted in the handler); in-kernel the same address is a direct-map garbage read (value flows into Vpd_step and the extrapolation above, then into pcdacTable and PHY registers) or a KVA-hole panic. Side observation: line 427 also reads VpdTable_I[ii][1] which FillVpdTable left uninitialized in this shape (intra-row uninit read). Flat curves require no EEPROM error -- equal calibrated pwr points produce them -- making this the easiest trigger of the three ar2317 siblings. Twin of DF-4622 (ar5413) / DF-4650 (ar2316) / DF-4662 (ar2413). Fix validated (sizeCurrVpdTable>=2 guard + clamped last-index): completes with no fault.", "exploit_chain": "crafted (or merely degenerate-flat) v3 EEPROM power curves on AR2317 card -> sizeCurrVpdTable==0 -> VpdTable_I[ii][0xFFFFFFFF/0xFFFFFFFE] wild reads at row+0x1FFFFFFFE -> direct-map garbage propagates into Vpd_step -> extrapolated pdadc values -> pcdacTable + 32 PHY register writes (ar2317.c:566-573) = radio misprogramming, or KVA-hole kernel panic. No uid0 route.", "evidence": "run.log mode 3: REPRODUCED: SIGSEGV si_addr=0xa00475dfe == expected wild READ address 0xa00475dfe + MATCH: wild OOB read proven; fix_run.log (===== fixC section): patched mode 3 completes with minPower=0x003e, no SIGSEGV.", "kernel_refs": [ "sys/dev/netif/ath/ath_hal/ar5212/ar2317.c:438", "sys/dev/netif/ath/ath_hal/ar5212/ar2317.c:445-446", "sys/dev/netif/ath/ath_hal/ar5212/ar2317.c:427", "sys/dev/netif/ath/ath_hal/ar5212/ar2317.c:452-461", "sys/dev/netif/ath/ath_hal/ah_eeprom_v3.h:291" ], "poc_changes": "Same harness as DF-4680 (mode 3); no kernel-code changes.", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "Validated on the guest: fix.diff (sizeCurrVpdTable >= 2 guard around the [-1]/[-2] Vpd_step reads with a Vpd_step=1 fallback, and a clamped vpdLastIdx for the extrapolate-above reference) applied to a copy of the pristine guest ar2317.c, function bodies re-extracted verbatim, harness rebuilt and re-run. Baseline SIGSEGVs at the wild address; patched mode 3 completes without fault (minPower=0x003e sane). fix.diff is git-apply-able against the pristine tree and was never applied to sys/.", "fix_evidence": "fix_run.log (===== fixC section: PATCHES_APPLIED, FIXED_BUILD_OK, no SIGSEGV: function completed) vs run.log mode 3; fix.diff in pack.", "attempts": 1, "notes": "Trigger needs no malformed EEPROM -- flat calibrated curves suffice. Known DF-1806 (pass 1) and DF-4681 (zero-gain) are different underflow triggers in the same function and were NOT re-reported here.", "recommended_fix": "Guard the sizeCurrVpdTable-1/-2 reads with a sizeCurrVpdTable >= 2 check (Vpd_step=1 fallback) and clamp the extrapolate-above last index (fix.diff)." } |