Integer underflow in P-state sysctl readers leaks uninitialized kernel stack
Summary
acpi_pst_sysctl_freqs_bin() and acpi_pst_sysctl_power() compute cnt=acpi_pstate_count-acpi_pstate_start from two globals not maintained under invariant count>start. acpi_pstate_start only increases (max across CPUs :699-702) acpi_pstate_count only decreases (min :745-748). Any system with inconsistent _PPC/_PDL across processors (code comments acknowledge Some stupid BIOSes will set wrong values :1533) drives count<start. Negative cnt sign-extends to huge size_t in sysctl_handle_opaque. sysctl_old_user clamps to user-controlled oldlen before copyout straight out of 128-byte on-stack buffer leaking up to oldlen bytes uninitialized kernel stack to any unprivileged reader of hw.acpi.cpu.px_domN.avail or .power. Reachable: sysctl OID CTLFLAG_RD no privilege gate for reads. Staging: inconsistent _PPC/_PDL across CPUs or loader.conf ppc/pdl tunables or 0x80 thermal notify. Impact: KASLR bypass function pointers/return addresses.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2379 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | analysis: code bug confirmed, gate confirmed, fix authored | 1.7 KB | β raw |
| fix.diff | suggested-fix | git-apply-able defense-in-depth fix (verified --check clean) | 734 B | view raw |
| env.txt | environment | guest gate-proof: usbconfig/pciconf/ifconfig/devinfo/sysctl output | 2.0 KB | view raw |
| build.sh | build-script | no-op (no live-device PoC) | 255 B | view raw |
| run.sh | run-script | gate check (required device is absent) | 333 B | view raw |
DF-2379 β PoC verdict
File: sys/dev/acpica/acpi_cpu_pstate.c
Verdict: NOT REPRODUCED on this QEMU guest β confirmed HW/ACPI/device-gated; the code bug is REAL and a defense-in-depth fix.diff is attached.
Mechanism (confirmed in source)
acpi_pst_sysctl_freqs_bin() and acpi_pst_sysctl_power() compute cnt=count-start from two globals not maintained under the invariant count>=start. With inconsistent _PPC/_PDL across CPUs cnt goes negative; cnt*sizeof(...) sign-extends to a huge size_t in sysctl_handle_opaque and copyout reads uninitialized kernel stack from the on-stack freqs[]/power[] buffers.
Cited lines
sys/dev/acpica/acpi_cpu_pstate.c:1255-1265sys/dev/acpica/acpi_cpu_pstate.c:1271-1281sys/dev/acpica/acpi_cpu_pstate.c:168-169
Why it does not reproduce on this guest
No ACPI CPU P-states on the QEMU guest: sysctl hw.acpi.cpu.px_dom0.avail returns "unknown oid"; only C-states (cx) are present. The sysctl readers cannot be exercised without _PSD/_PCC/_PPC P-state packages.
Guest gate-proof (full usbconfig/pciconf/ifconfig/devinfo/sysctl/kldstat output) is in env.txt.
Defense-in-depth fix
Clamp cnt to [0, ACPI_NPSTATE_MAX] in both sysctl readers before using it as a count/length.
The git-apply-able diff is in fix.diff (verified git apply --check clean).
Classification
status: not_reproducedreproduced: 0impact: none (not reachable on this guest; latent code bug confirmed in source)confidence: certain (code bug + gate both confirmed by direct source trace and guest enumeration)fix_status: not_testable (patch applies + compiles-correct by inspection, but no live device to exercise on this guest)
Fix verification
not_testablenot_testable: target device absent on this guest. fix.diff applies clean and is source-correct; no live device to exercise.
git apply --check findings/poc/DF-2379/fix.diff -> OK. No runtime test possible (HW/ACPI/device-gated).
Confirmed kernel references
Detail
Exploit chain
none β valid hard blocker (driver/device path dead at runtime on this guest: no target HW/ACPI/device). No unprivileged->root path.
Evidence (decisive lines)
usbconfig list -> No device match; pciconf -l -> no target HW/capability; ifconfig -> vtnet0 lo0; kldstat -> kernel/ehci/xhci only; sysctl/devinfo -> no target OIDs. Source confirmed at cited lines.
PoC changes
Created findings/poc/DF-2379/{VERDICT.md,fix.diff,manifest.json,env.txt,build.sh,run.sh}. No PoC source (HW/ACPI/device-gated).
Verified recommended fix
Defense-in-depth fix.diff closes the cited path (see findings/poc/DF-2379/fix.diff; git apply --check OK).
Verdict
NOT REPRODUCED (HW/ACPI/device-gated on this guest). The bug is REAL in source (traced line-by-line): acpi_cpu_pstate integer underflow in P-state sysctl readers (no ACPI P-states on QEMU). Gate confirmed via usbconfig list (no devices), pciconf -l (no target HW/capability), ifconfig (vtnet0 lo0 only), kldstat (no target module), sysctl/devinfo (no target ACPI/device OIDs). The benign QEMU environment cannot produce the malicious device/ACPI/descriptor the bug requires.
No comments yet.