⬢ DragonFlyBSD Kernel Audit
DF-5669 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5669",
  "status": "reproduced",
  "verdict": "The deprecated-but-live ACPIIO_SETSLPSTATE ioctl (acpi.c:3451) bypasses the platforms explicit suspend not supported gate (acpi_ReqSleepState, acpi.c:2417-2420 -> EOPNOTSUPP) and drives the pc64 suspend machinery whose machdep half is stubbed out (acpi_wakeup.c:51-59, invoked from acpi_machdep.c:60). Reproduced 4/4 on the guest: as root, ioctl(SETSLPSTATE, S3/S4) returns 0 (success) while dmesg records device_suspend failed per call \u2014 the entire device tree is walked through suspend with bus_generic_suspends inline partial resume (subr_bus.c:2894-2908), and the failure is masked because acpi_EnterSleepState leaves status=AE_OK from AcpiGetSleepTypeData through the device_suspend-failure break (acpi.c:2624-2627, 2698). Unprivileged users are correctly denied (EPERM on O_RDWR open of root:wheel 0644 /dev/acpi). On suspend-clean hardware the same path continues into a phantom sleep cycle (AcpiEnterSleepStatePrep/_PTS -> no-op acpi_sleep_machdep -> ACPI_SS_SLEPT -> AcpiLeaveSleepState/_WAK + DEVICE_RESUME on a machine that never slept, with icu_reinit/elcr_resume never called \u2014 zero callers), an unvalidated full device-tree teardown/rebuild on a platform that declares the operation unsupported. Impact ceiling: privileged local DoS / kernel driver-state corruption; no unprivileged escalation path exists.",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "exploit_chain": "",
  "evidence": "run.log: ioctl() = 0, errno = 0 for the deprecated ioctl vs run.reqstate.log: errno = 45 (Operation not supported) for the gated one; dmesg.txt: one acpi0: device_suspend failed per deprecated-ioctl call (4 lines, 4 calls); run.unpriv.log: unpriv open denied; VERDICT.md: full path trace with the guest-specific driver-veto blocker for the deeper phantom stages",
  "kernel_refs": [
    "sys/dev/acpica/acpi.c:3451",
    "sys/dev/acpica/acpi.c:2378",
    "sys/dev/acpica/acpi.c:2557",
    "sys/dev/acpica/acpi.c:2417",
    "sys/dev/acpica/acpi.c:2624",
    "sys/dev/acpica/acpi.c:2653",
    "sys/dev/acpica/acpi.c:2669",
    "sys/dev/acpica/acpi.c:3424",
    "sys/platform/pc64/acpica/acpi_wakeup.c:51",
    "sys/platform/pc64/acpica/acpi_wakeup.c:57",
    "sys/platform/pc64/acpica/acpi_machdep.c:60",
    "sys/kern/subr_bus.c:2894",
    "sys/contrib/dev/acpica/source/components/hardware/hwsleep.c:408"
  ],
  "poc_changes": "n/a \u2014 trigger authored fresh for this files audit (no orchestrator seed existed); ACPIIO_SETSLPSTATE/_IOW(P,3,int) defined inline from sys/dev/acpica/acpiio.h:38 to avoid include-path issues",
  "attempts": 6,
  "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": 420,
  "guest_dirty": 0,
  "build_cmd": "scp -F dfbsd-qemu/config findings/poc/DF-5669/setslp.c dfbsd:/root/ && vm.sh run_root cc -O -o /root/setslp /root/setslp.c",
  "run_cmd": "vm.sh run_user /tmp/setslp 3; vm.sh run_root /root/setslp 3 req; vm.sh run_root /root/setslp 3; dmesg | tail; vm.sh run_root /root/setslp 4; uptime",
  "code_hash": "cf50666804090d58019ccd9b561a3ea2d0d46dd6e3bfa9c0b66b9979b8fd6551",
  "notes": "Guest stayed healthy across all runs (uptime continuous, no panic) because a driver vetoes DEVICE_SUSPEND deterministically on this guest \u2014 the veto halts the flow at stage 2 of 5, before AcpiEnterSleepStatePrep/the no-op stub/AcpiLeaveSleepState; those deeper phantom stages are code-cited in VERDICT.md. S5 via the deprecated ioctl intentionally remains allowed by the fix (poweroff is a supported operation, identical to REQSLPSTATEs S5 handling). Complementary already-filed finding: DF-5654 (elcr_resume dead code \u2014 not re-reported).",
  "recommended_fix": "Route ACPIIO_SETSLPSTATE through acpi_ReqSleepState() so the platforms EOPNOTSUPP gate applies; optionally also set status=AE_ERROR on the device_suspend-failure break in acpi_EnterSleepState.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "fix.diff authored and line-verified against acpi.c:3451-3456 (routes the deprecated ioctl through the acpi_ReqSleepState gate, keeping S5 poweroff working); not kernel-rebuilt/validated because this is a Low-severity logic finding, not reproduced memory corruption, and the audit contract requires the single-fix kernel cycle only for memory-corruption findings.",
  "fix_evidence": "fix.diff (git-apply-able vs sys/dev/acpica/acpi.c); baseline behavior in run.log/dmesg.txt"
}