Missing zero-validation on machdep.acpi_timer_freq sysctl causes divide-by-zero kernel panic
Summary
acpi_timer_sysctl_freq accepts any u_int value written by root and forwards unchanged to cputimer_set_frequency(). Writing 0 executes (1000000LL<<32)/0 and (1000000000LL<<32)/0 in kern_cputimer.c:190-191 raising x86 #DE panicking kernel. Only check present (:316) validates CURRENT frequency not user-supplied new value so provides no protection. OID CTLTYPE_INT|CTLFLAG_RW no CTLFLAG_SECURE/ANYBODY so write requires SYSCAP_NOSYSCTL_WR (root-equivalent). Local root can panic deterministically with single privileged sysctl write. No special hardware state required beyond attached ACPI timer (default on virtually all x86_64 with ACPI). [VERIFIED pass2: reproduced on STOCK - sysctl acpi_timer_freq 0 Fatal trap 18 divide fault at cputimer_set_frequency+0x10; root-gated deterministic DoS; EINVAL fix-validated]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2392 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 515 B | β raw | |
| VERDICT.md | β | 1.3 KB | β raw | |
| env.txt | β | 145 B | view raw | |
| fix.diff | β | 446 B | view raw | |
| fixed.log | β | 241 B | view raw | |
| panic.txt | β | 332 B | view raw | |
| run.sh | β | 121 B | view raw | |
| verdict.json | β | 1.7 KB | view raw |
DF-2392 - machdep.acpi_timer_freq=0 divide-by-zero panic
Reproduce (STOCK kernel, root)
sysctl -w machdep.acpi_timer_freq=0 -> Fatal trap 18: integer divide fault while in kernel mode Stopped at cputimer_set_frequency+0x10: divq %rsi,%eax
The only validation in acpi_timer_sysctl_freq (acpi_timer.c:310-311) checks the CURRENT acpi_cputimer.freq, never the user-supplied new value.
Fixed kernel (fix.diff: reject freq==0 with EINVAL)
sysctl machdep.acpi_timer_freq=0 -> Invalid argument (no panic)
DF-2392 VERDICT
Status: reproduced (reproduced) Impact: panic Confidence: certain Attempts: 1
STOCK kernel (X86_64_GENERIC #0): sysctl -w machdep.acpi_timer_freq=0 is accepted by acpi_timer_sysctl_freq (only the CURRENT frequency is validated at acpi_timer.c:310-311) and forwarded unchanged to cputimer_set_frequency, which divides by it - Fatal trap 18 integer divide fault, Stopped at cputimer_set_frequency+0x10 (divq %rsi,%eax), guest dies. Single privileged sysctl write, deterministic, no special hardware state. Fixed kernel rejects the write with EINVAL (Invalid argument).
Kernel references
Guest
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
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
Exploit chain
root-only deterministic kernel panic (local DoS); SYSCAP_NOSYSCTL_WR gate quantified - write requires root, read is world-readable
Evidence (decisive lines)
panic.txt (Fatal trap 18 ... Stopped at cputimer_set_frequency+0x10: divq %rsi,%eax); fixed.log (sysctl machdep.acpi_timer_freq=0 -> Invalid argument, RC=1)
PoC changes
run.sh from the seed pack ran as-is on a fresh stock boot
Verified recommended fix
see fix.diff
Verdict
STOCK kernel (X86_64_GENERIC #0): sysctl -w machdep.acpi_timer_freq=0 is accepted by acpi_timer_sysctl_freq (only the CURRENT frequency is validated at acpi_timer.c:310-311) and forwarded unchanged to cputimer_set_frequency, which divides by it - Fatal trap 18 integer divide fault, Stopped at cputimer_set_frequency+0x10 (divq %rsi,%eax), guest dies. Single privileged sysctl write, deterministic, no special hardware state. Fixed kernel rejects the write with EINVAL (Invalid argument).
No comments yet.