⬢ DragonFlyBSD Kernel Audit
DF-5145 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5145",
  "status": "reproduced",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "REPRODUCED on the audit-tree kernel+module: an ACPI IPI0001 device with _IFT=4 (SSIF) makes ipmi_acpi_attach() return 0 on a completely uninitialized softc (ipmi_acpi.c:104-109 \u2014 no ipmi_enqueue_request, no lockinit, no cdev). kldunload then runs ipmi_detach -> ipmi_set_watchdog(sc,0) (ipmi.c:887, DragonFly-specific) -> ipmi_submit_driver_request -> sc->ipmi_enqueue_request(sc,req) == NULL call: Fatal user address access from kernel mode from kldunload at 0000000000000000, trap 12, rip=0, DDB, guest dead (panic.txt). Fix validated in the same setup: with fix.diff the attach refuses with ENXIO (attach returned 6) and kldunload completes cleanly (UNLOAD_RC_0_CLEAN). Firmware/config-gated availability impact only (CWE-476); no attacker control of the call target.",
  "exploit_chain": "firmware/VM config (IPI0001 + _IFT=4 SSDT) -> ipmi_acpi probe match -> dead-softc attach (return 0) -> module unload/teardown -> NULL indirect call -> fatal trap 12 at address 0 -> DDB (system down). No escalation: target address is fixed NULL, no memory corruption.",
  "evidence": "panic.txt (decisive serial capture: Fatal user address access from kernel mode from kldunload at 0000000000000000 / rip=0x0); run.log (baseline + fix sequence); VERDICT.md (full narrative incl. fix validation transcript); ssdt_gen.py (trigger generator); env.txt (guest uname)",
  "kernel_refs": [
    "sys/dev/misc/ipmi/ipmi_acpi.c:104",
    "sys/dev/misc/ipmi/ipmi_acpi.c:109",
    "sys/dev/misc/ipmi/ipmivars.h:132",
    "sys/dev/misc/ipmi/ipmi.c:584",
    "sys/dev/misc/ipmi/ipmi.c:719",
    "sys/dev/misc/ipmi/ipmi.c:887",
    "sys/dev/misc/ipmi/ipmi.c:940"
  ],
  "poc_changes": "Seed concept replaced entirely: trigger is a hand-assembled SSDT (ssdt_gen.py), not a C program. Required: byte-swapped EISAID (0x01000926), ACPICA 2-byte PkgLength form (byte1<<4 | byte0&0xF), Buffer(N) size TermArg, 1-byte small-IO _LEN, _SRV present; audit-tree kernel build (stock prebuilt guest kernel ignores RSDT-SSDT devices); trigger via kldunload (plain reboot does not tear the module down).",
  "attempts": 9,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #1: Wed Sep 30 08:54:01 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64",
  "runtime_sec": 5400,
  "guest_dirty": 1,
  "build_cmd": "guest: cd /usr/src/sys/dev/misc/ipmi && make; kernel: cd /usr/src && make -j6 nativekernel KERNCONF=X86_64_GENERIC && make installkernel KERNCONF=X86_64_GENERIC",
  "run_cmd": "QEMU_EXTRA=-acpitable file=ssdt-ipmi-ssif.aml dfbsd-qemu/vm.sh up; vm.sh run_root kldload /root/ipmi-audit.ko; vm.sh run_root kldunload ipmi-audit",
  "code_hash": "b9d0bdf3a2381c8a4874b070697dea1f7fcd71953bd7630c698f6ba8e968b88a",
  "notes": "Plain reboot of the kldloaded config shut down cleanly in this test; the module SYSUNINIT(ipmi_unload) did not tear the device down on that path. Built-in-kernel shutdown/unload paths remain structurally exposed (any ipmi_detach on the dead softc). The ipmi_acpi singleton guard itself is present and correct (unlike DF-5076s ipmi2_pci). vinumparser.c co-audited in this batch: clean (DF-2141/DF-4132 known, not re-reported).",
  "recommended_fix": "ipmi_acpi.c SSIF case: return ENXIO instead of return(0) (never attach a dead softc); plus defensive NULL guard on ipmi_enqueue_request in ipmi_submit_driver_request (see fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "fix.diff applied to guest /usr/src (module-only rebuild, same kernel, same SSDT): attach now refuses (ipmi0: SSIF interface not supported on ACPI + device_probe_and_attach: ipmi0 attach returned 6), no device attached, kldunload returns 0, guest stays alive. Baseline with pristine module in the identical setup panics (trap 12, rip=0). Bad behavior GONE with fix.",
  "fix_evidence": "fix.diff; VERDICT.md Fix validation section; guest transcript: LOADED_FIXED / attach returned 6 / UNLOAD_RC_0_CLEAN / NO_IPMI_LOADED / STILL_ALIVE"
}