UAF on clockmod_dom in clockmod_dom_sysctl_select across sysctl_handle_string sleep
Summary
clockmod_dom_sysctl_select is two-phase: L426 lwkt_serialize_enter; L428-429 read current duty; L430 lwkt_serialize_exit; L432 sysctl_handle_string SLEEPS on user copy; L436 lwkt_serialize_enter; L438 dom->dom_flags deref; L454 TAILQ_FOREACH dom->dom_list. During sleep at L432 concurrent clockmod_dom_detach L217-242 of last CPU in domain: acquires released lock L221 clears ACTIVE L235 TAILQ_REMOVE L237 TAILQ_EMPTY L238 clockmod_dom_destroy L239. destroy L345-360 TAILQ_REMOVE from list sysctl_ctx_free rip OIDs kfree(dom) L353. Handler resumes L436 reacquires lock on freed memory L438 dom->dom_flags UAF. sysctl_remove_oid_locked oid_running drain kern_sysctl.c:391-398 is dead code (oid_running never incremented in tree grep). Root trigger: sysctl write on machdep.clockmod_domN.select + devctl cpu detach race. Impact: kernel panic DoS; theoretical code-exec with heap grooming. Fix: hold lock across entire handler or refcount dom. [PASS-2 MECHANISM REFUTED LIVE: sysctl_ctx_free drains in-flight handlers via the per-cpu gd_sysctllock xlock - kldunload blocked 4s in mirror test, post-sleep reads intact; pass-1 reproduced verdict was source-only. Recommend re-triage to disputed/invalid (evidence findings/poc/DF-4823/mechanism_check_df1906/)]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1906 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | git-apply-able fix for the cited bug | 429 B | view raw |
| VERDICT.md | verdict | source-confirmation analysis | 1.0 KB | β raw |
| build.sh | build-script | N/A (source-only) | 65 B | view raw |
| run.sh | run-script | N/A (source-only) | 89 B | view raw |
DF-1906 VERDICT
Verdict: REPRODUCED (source-confirmed)
Impact: Low (driver-level NULL deref / OOB / leak / DoS β hardware-gated)
Mechanism: clockmod_dom_sysctl_select is two-phase: L426 lwkt_serialize_enter; L428-429 read current duty; L430 lwkt_serialize_exit; L432 sysctl_handle_string SLEEPS on user copy; L436 lwkt_serialize_enter; L438
Citation: sys/dev/powermng/clockmod/clockmod.c:430-454
Fix: Applied fix.diff β compiles in batch kernel build (rc=0, -Werror).
Verification method: Source-only line-by-line trace of cited path:line. Low-severity driver bug; PoC trigger requires specific hardware or root context. Confirmed the cited vulnerable pattern exists in source.
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
fixedfix.diff compiled in batch kernel build rc=0 -Werror
fix.diff compiled in batch kernel build rc=0 -Werror
Confirmed kernel references
Detail
Exploit chain
none - refuted at runtime
Evidence (decisive lines)
findings/poc/DF-4823/mechanism_check_df1906/run.log
Verdict
PASS-2 MECHANISM REFUTATION (live, clockmod audit 2026-09-24): the claimed UAF (clockmod_dom freed across the sysctl_handle_string sleep during kldunload) does NOT exist - kern_sysctl.c:1572-1574 holds the per-cpu shared gd_sysctllock across the handler including its sleep, and sysctl removal (_sysctl_xlock) takes every cpu's lock exclusively, so sysctl_ctx_free in the unload path BLOCKS until in-flight handlers return (mirror-module test: kldunload blocked 4s until the sleeping handler completed; post-sleep reads intact). The oid_running drain loop at kern_sysctl.c:391 is dead code but redundant. DF-1906's pass-1 'reproduced' verdict was source-confirmed only (empty build_cmd/run_cmd). Recommend re-triage: downgrade to disputed/invalid or re-scope to the dead-code oid_running only.
No comments yet.