⬢ DragonFlyBSD Kernel Audit
DF-4705 / verdict.json
← back to finding ↓ download raw
{
  "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"
}