⬢ DragonFlyBSD Kernel Audit
DF-5006 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5006",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "UNTESTED by design (contract: Low severity + privileged-only trigger; guest path unreachable). Code defect is certain: acpi_cpu.c installs an ACPI_DEVICE_NOTIFY handler with the softc as context (:252), two sysctl contexts (:171/:180) that children hang handlers on (acpi_cpu_cstate.c:759-774), and a sensordev (:233), but device_detach is bare bus_generic_detach (:67) \u2014 nothing is ever removed. On driver/module detach newbus frees the softc (subr_bus.c:1941-1944) while the handler, sysctl OIDs and sensordev keep referencing it: the next AML Notify(cpu,0x80/0x81) runs acpi_cpu_notify (:324-342) over freed memory (UAF call through cpu_cst_notify/cpu_pst_notify) and sysctl access hits handlers with dangling ctx. Attach error paths (:236-237, :243-244) leak the same resources without any unload. Gating: only reachable by unloading an acpi.ko built as a module (root-only, non-default config); guest has acpi compiled-in (kldunload acpi -> cant find file, env_probe.txt) so the path cannot be exercised there. fix.diff adds a real acpi_cpu_detach + error-path cleanup (modeled on the sibling drivers that DO remove handlers, e.g. acpi_thermal.c:384).",
  "exploit_chain": "",
  "evidence": "fix.diff (proposed teardown); env_probe.txt (guest: cpu_cst0..5 live, acpi compiled-in, kldunload refused \u2014 path unreachable on guest)",
  "kernel_refs": [
    "sys/dev/acpica/acpi_cpu.c:67",
    "sys/dev/acpica/acpi_cpu.c:233",
    "sys/dev/acpica/acpi_cpu.c:252",
    "sys/dev/acpica/acpi_cpu.c:324",
    "sys/dev/acpica/acpi_cpu_cstate.c:751",
    "sys/kern/subr_bus.c:1941"
  ],
  "poc_changes": "no seed; no runnable PoC (path gated on module-built acpi + kldunload)",
  "attempts": 0,
  "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": 0,
  "guest_dirty": 0,
  "build_cmd": "",
  "run_cmd": "",
  "code_hash": "",
  "notes": "hub-level pass-2 result for acpi_cpu.c. The child parsers (_CST/_PSS arrays, sysctl string handlers) are separate files with existing pass-1 findings (DF-1480/1554/2377/2378/2379/4261) and were not re-audited as findings here. Out-of-file lead noted for the acpi.c audit: acpi_eval_osc (sys/dev/acpica/acpi.c:1296-1361) never type-checks the _OSC return object nor its length before reading ((uint32_t*)retobj->Buffer.Pointer)[0..count-1] (:1330,:1345,:1354) \u2014 a non-Buffer return or short buffer from crafted AML is an OOB read/type-confusion read reachable from acpi_cpu_attach:209.",
  "recommended_fix": "add acpi_cpu_detach: AcpiRemoveNotifyHandler before bus_generic_detach, then sysctl_ctx_free(glob+pcpu) and sensordev_deinstall; fix attach error paths to free the same (fix.diff)",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff authored (real detach + error-path cleanup); not validated: the detach path is unreachable on this guest (acpi compiled into the kernel) and building a module-acpi custom kernel was out of scope for a Low finding.",
  "fix_evidence": "fix.diff"
}