UAF: sysctl sensor read races kfree of sensor arrays in detach
Summary
aibs_detach calls sensordev_deinstall then immediately kfrees sc->sc_asens_{volt temp fan}. Per-sensor sysctl OIDs were created with arg1=sens (struct ksensor* into sc->sc_asens_*). sysctl framework SUPPOSED to drain in-flight handlers via oid_running loop at kern_sysctl.c:391-398 BUT oid_running NEVER incremented anywhere in kernel (grep confirms no write site). Additionally sysctl_find_oid walks OID tree lockless SLIST_FOREACH. Window: reader obtains raw oid pointer -> detach frees OID struct and sensor arrays -> reader dereferences freed oid->oid_lock and freed ks->desc via memcpy(us->desc ks->desc 32). Systemic framework issue affecting ALL sensor drivers freeing sensor storage in detach. Unprivileged user reads sensors world-readable racing root kldunload or VM host ACPI hot-unplug. [VERIFIED pass2: race not staged but framework claim verified - oid_running read-only kernel-wide so the kern_sysctl drain loop is dead code and detach kfrees sensor arrays under live oid arg1; functional-drain fix compile-validated]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2396 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 788 B | β raw | |
| VERDICT.md | β | 1.5 KB | β raw | |
| env.txt | β | 145 B | view raw | |
| fix.diff | β | 728 B | view raw | |
| run.log | β | 802 B | view raw | |
| run.sh | β | 121 B | view raw | |
| verdict.json | β | 1.7 KB | view raw |
DF-2396 - sysctl sensor race vs detach: NOT staged (rig wedge)
Claim verification (source)
- kern_sysctl.c:391-398:
while (oidp->oid_running > 0) tsleep(...) - grep across sys/: oid_running is NEVER incremented - the drain is dead code; sysctl_root invokes oid->oid_handler with no running-marker.
- aibs_detach (atk0110.c:267-275) kfrees sc_asens_* immediately after sensordev_deinstall while per-sensor oid arg1 pointers reference them.
Runtime
The race staging required a live aibs sensor device; the verbatim-attach interposition wedged the harness guest (DF-2395 pack), so no race window was actually exercised.
fix.diff (compile-validated): atomic oid_running++/-- + wakeup around
the handler invocation in sysctl_root, making the existing drain loop functional.
DF-2396 VERDICT
Status: not_reproduced Impact: corruption Confidence: likely Attempts: 1
No runtime race was executed: the aibs verbatim attach (which creates the sensor sysctl OIDs) wedged the harness guest (see DF-2395 pack), so the reader-vs-detach race could not be staged. The framework claim verifies cleanly in source: oid_running is read in exactly one place (kern_sysctl.c:391-398 drain loop) and grep confirms NO increment site anywhere in the kernel - the drain loop can never observe oid_running>0, so sysctl_remove_oid frees oid+arg1 storage without waiting for in-flight handlers. The aibs-side precondition (sensordev_deinstall then immediate kfree of sc_asens_* at atk0110.c:267-275) is real. fix.diff (increment/decrement+wakeup around the handler call) compile-validated in the fixed build.
Kernel references
sys/dev/acpica/aibs/atk0110.c:268sys/kern/kern_sysctl.c:391sys/kern/kern_sysctl.c:395sys/sys/sysctl.h:168
Guest
DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #7: Sat Oct 24 00:08:04 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/ACHARNESS x86_64
Fix validation
See fix.diff and README.md for the baseline/fixed A/B outputs (run.log / fixed.log).
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md source analysis (oid_running read-only); race not staged (rig wedge)
PoC changes
race staging depended on the aibs rig that wedged; framework analysis performed instead
Verified recommended fix
see fix.diff
Verdict
No runtime race was executed: the aibs verbatim attach (which creates the sensor sysctl OIDs) wedged the harness guest (see DF-2395 pack), so the reader-vs-detach race could not be staged. The framework claim verifies cleanly in source: oid_running is read in exactly one place (kern_sysctl.c:391-398 drain loop) and grep confirms NO increment site anywhere in the kernel - the drain loop can never observe oid_running>0, so sysctl_remove_oid frees oid+arg1 storage without waiting for in-flight handlers. The aibs-side precondition (sensordev_deinstall then immediate kfree of sc_asens_* at atk0110.c:267-275) is real. fix.diff (increment/decrement+wakeup around the handler call) compile-validated in the fixed build.
No comments yet.