β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-4793

ar9287SetPowerCalTable: non-2GHz channel leaves pCalBChans=NULL/numPiers=0, unguarded per-chain walk NULL-derefs pList[0] in ath_ee_getLowerUpperIndex (kernel panic)

Summary

The 2GHz-only dataset selection has no else; the per-chain loop still runs for non-2GHz channels and ath_ee_getLowerUpperIndex derefs pList[0] unconditionally (ah.c:1273). Reachability proven in-tree: DF's ar5416FillCapabilityInfo ORs HAL_MODE_11A under GMODE (a DF divergence), unconditional 5GHz edges, 5GHz-permissive regdomain EEPROM admits 11a channels, and SetChannel survives freq>=4800 so the reset reaches the NULL deref. Privileged channel config or forged EEPROM trigger; panic only. Classic family shapes ABSENT (open-loop control). Early-return guard fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4793 Β· 1 files
FileTypeDescriptionSize
verdict.json file 1.7 KB view raw

Fix verification

not_testable
per-fix-DF-4793

Confirmed kernel references

Detail

Exploit chain

AR9287 + 5GHz-permissive EEPROM regdomain: ifconfig wlan0 create wlandev ath0 mode 11na; channel 149 -> ar9287Reset -> SetPowerCalTable -> ar9287olcGetTxGainIndex(NULL,0) -> ath_ee_getLowerUpperIndex derefs NULL -> kernel panic

Evidence (decisive lines)

findings/poc/DF-4793/ (this verdict; full in-tree reachability trace in reviewer notes)

Verdict

Hardware-gated NULL-deref: ar9287SetPowerCalTable fills pCalBChans/numPiers only in the 2GHz branch, then walks chains unconditionally - a non-2GHz channel passes (NULL,0) into ath_ee_getLowerUpperIndex which derefs pList[0] (ah.c:1273). Reachability chain proven in-tree: DF's ar5416FillCapabilityInfo ORs HAL_MODE_11A under GMODE (ar5416_attach.c:904-914, a DF divergence from FreeBSD), 5GHz edges unconditionally 4915-6100, 5GHz-permissive regdomain EEPROM SKU admits 11a channels, and ar9287SetChannel survives freq>=4800 (modulo, not divide) so the reset reaches the NULL deref. Classic ar9002 family shapes (pdadc/numPdGain/FillVpdTable) structurally ABSENT here (open-loop control). Trigger: privileged channel config or forged EEPROM; fixed-NULL read = panic, no corruption. No ath NIC on the QEMU guest. Early-return guard fix authored.