DF-4374 / verdict.json
{ "finding_id": "DF-4374", "status": "not_reproduced", "reproduced": 0, "impact": "none", "confidence": "likely", "verdict": "Lifetime race between world-readable dev.ath.N.* sysctl read handlers and ath(4) driver detach. Most handlers (txantenna if_ath_sysctl.c:260, diversity :320, diag :351, tpscale :380, tpc :407, rfkill :434, rfsilent :567, tpack :606, tpcts :631, intmit :656) call into the HAL outside ATH_LOCK with no sc_invalid check; ath_detach frees sc_ah at if_ath.c:1436 and the PCI layer unmaps the register BARs before device_sysctl_fini (subr_bus.c:2151) removes the sysctl oids, and the per-oid sysctl lock (kern_sysctl.c:1460-1482) protects only the oid, not the softc. An unprivileged reader parked between ATH_UNLOCK and the HAL call during root-initiated detach (kldunload if_ath / hot-remove) dereferences freed HAL state or reads unmapped MMIO -> kernel page fault panic. Reader side needs no privilege (writes are gated by SYSCAP_NOSYSCTL_WR per kern_sysctl.c:1446-1447, reads are not). Not executed: the audit QEMU guest has no Atheros hardware (dev.ath absent, no 0x168c PCI device); probe run honestly reports absence. Impact ceiling: race-condition local DoS; detach side is privileged, hence severity Low.", "exploit_chain": "", "evidence": "VERDICT.md (4-step lifetime proof with citations); run.log + env.txt (guest: dev.ath unknown oid, NO_ATHEROS_PCI, unprivileged uid=1001 probe); fix.diff (representative ATH_LOCK + sc_invalid pattern, git-apply-able); README.md", "kernel_refs": [ "sys/dev/netif/ath/ath/if_ath_sysctl.c:260", "sys/dev/netif/ath/ath/if_ath_sysctl.c:320", "sys/dev/netif/ath/ath/if_ath_sysctl.c:351", "sys/dev/netif/ath/ath/if_ath.c:1436", "sys/kern/subr_bus.c:2151", "sys/kern/kern_sysctl.c:1446", "sys/kern/kern_sysctl.c:1460" ], "poc_changes": "Trigger is a shell reader-storm (sysctl(8)) raced against root kldunload; no C needed. Guest probe reports hardware absence.", "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": 45, "guest_dirty": 0, "build_cmd": "none (shell trigger)", "run_cmd": "sh trigger_df4374.sh (unprivileged)", "code_hash": "6e0a96a6bad685f34ee0abfaf348967abef8e63becffbdcc747ba80ae181c66a", "notes": "No ath(4) hardware on the audit guest; the reader-storm-vs-kldunload race can only be exercised on real hardware. Negative results for the rest of the hunt list are in the final report: no station-table sysctls, no proc/debugfs files, no getregdump consumers (DF-4320/DF-4321 own those), txantenna bounds-checked, HAL CHECK_HANGS always sets *result on AH_TRUE (ar5416_misc.c:543-554), writes are root-only.", "recommended_fix": "In every affected handler, take ATH_LOCK, bail with ENXIO when sc->sc_invalid, and keep the lock across the HAL interaction (pattern in fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff shows the representative corrected ath_sysctl_txantenna (git-apply-able, verified); the same shape must be applied to diversity/diag/tpscale/tpc/rfkill/rfsilent/tpack/tpcts/intmit. Cannot validate on the guest (no ath hardware).", "fix_evidence": "fix.diff; VERDICT.md Fix validation section" } |