DF-4705 / verdict.json
{ "finding_id": "DF-4705", "status": "inconclusive", "reproduced": 0, "impact": "none", "confidence": "certain", "verdict": "ar5210GetDiagState HAL_DIAG_EEREAD (ar5210_misc.c:642) dereferences args==NULL when SIOCGATHDIAG omits ATH_DIAG_IN while setting ad_in_size=2: ath_ioctl_diag (if_ath_ioctl.c:174-192) only allocates indata under ATH_DIAG_IN but forwards insize unconditionally, so the argsize check at :638 passes and *(const uint16_t *)args reads address 0 -> kernel page-fault panic. Distinct from known DF-1819 (the *result NULL write in the same expression; this trigger supplies ATH_DIAG_DYN so *result is valid) and the ar5210 instance of the DF-4670 args==NULL family; the unconditional generic fallback ah.c:904 has the identical deref. Runtime confirmation impossible on the audit guest: no Atheros PCI device, no ath interface, no ATH_DIAGAPI option in X86_64_GENERIC and no ath_ioctl_diag symbol in the stock if_ath.ko (all verified, guest_session.log); the trigger builds (CC_EXIT=0) and runs harmlessly (ENXIO) on the guest, proving the PoC side correct and the block purely hardware/option-gated.", "exploit_chain": "", "evidence": "guest_session.log (uname, pciconf 0x168c absent, ifconfig 0 ath, GENERIC 0 ATH_DIAGAPI matches, nm if_ath.ko 0 ath_ioctl_diag, nm ath_hal.ko shows ar5210GetDiagState present); trigger.c (ATH_DIAG_DYN|HAL_DIAG_EEREAD, ad_in_size=2, no ATH_DIAG_IN); build.log CC_EXIT=0; run.log ioctl -> -1 errno=6 ... no panic; VERDICT.md full trace if_ath_ioctl.c:174->ar5210_misc.c:638,642", "kernel_refs": [ "sys/dev/netif/ath/ath_hal/ar5210/ar5210_misc.c:638", "sys/dev/netif/ath/ath_hal/ar5210/ar5210_misc.c:642", "sys/dev/netif/ath/ath/if_ath_ioctl.c:174", "sys/dev/netif/ath/ath/if_ath_ioctl.c:180", "sys/dev/netif/ath/ath_hal/ah.c:904" ], "poc_changes": "seed trigger rewrote: trimmed struct ath_diag from if_athioctl.h (not in guest /usr/include), set ad_id=ATH_DIAG_DYN|HAL_DIAG_EEREAD (0x8011) with ad_in_size=2 and NO ATH_DIAG_IN so the ONLY NULL deref on line 642 is args (discriminates from DF-1819); ioctl request re-derived as _IOWR(i,138,...)", "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": 95, "guest_dirty": 0, "build_cmd": "cc -O -o /root/poc/trigger /root/poc/trigger.c", "run_cmd": "/root/poc/trigger", "code_hash": "b8f5f2e0fc55898bb999e7b3d41f498d41e0f0dbaa221eca0581a04ca27ab0bc", "notes": "hw+option-gated (ar5210 NIC + options ATH_DIAGAPI, neither in stock GENERIC); no privilege check on SIOCGATHDIAG per DF-4320; fix.diff also patches the identical unconditional fallback at ah.c:902-904", "recommended_fix": "reject NULL args/result in the HAL_DIAG_EEREAD case of ar5210GetDiagState and the generic ath_hal_getdiagstate fallback (see fix.diff)", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix validation impossible on this guest: baseline requires ar5210 hardware + ATH_DIAGAPI kernel (both absent); fix.diff authored from line-accurate root cause and mirrors the DF-1819-style NULL guards extended to args", "fix_evidence": "fix.diff (ar5210_misc.c + ah.c hunks); guest_session.log gate evidence" } |