⬢ DragonFlyBSD Kernel Audit
DF-5115 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-5115",
  "status": "untested",
  "reproduced": false,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Static logic is certain and fully traced: ips_pci_detach (ips_pci.c:202-208) clears sc->configured BEFORE ips_adapter_free can return EBUSY, so after any failed detach (open ipsd disk / IPS_DEV_OPEN / nonempty command queue, ips.c:529-537) the driver is permanently wedged in the detached state: ips_pci_shutdown skips the cache flush (ips_pci.c:218) and every retried detach takes the configured==0 path returning success WITHOUT ips_adapter_free/ips_pci_free - the IRQ installed at attach (ips_pci.c:131-133) keeps sc as handler argument past softc destruction, giving an interrupt-context UAF read/write once the unit is deleted (kldunload retry). Not reproduced because the single audit guest has no IBM/Adaptec ServeRAID controller (pciconf evidence in env.txt); probe never matches so the code path has no instance to run on. Root-privileged trigger + hardware requirement cap severity at Low.",
  "exploit_chain": "requires hardware: root holds ipsd busy -> kldunload ips (EBUSY, configured:=0) -> kldunload ips again (returns 0, IRQ live, softc freed at unit delete) -> next adapter interrupt -> ips_morpheus_intr/ips_copperhead_intr on freed softc -> interrupt-context UAF read/write (crash; heap grooming theoretical)",
  "evidence": "VERDICT.md (full trace); env.txt (guest pciconf shows no 1014:01bd/1014:002e/9005:0250 device; ips.ko loads but never probes); trigger.sh (hardware-gated trigger, exit 42 on this guest)",
  "kernel_refs": [
    "sys/dev/raid/ips/ips_pci.c:202",
    "sys/dev/raid/ips/ips_pci.c:203",
    "sys/dev/raid/ips/ips_pci.c:205",
    "sys/dev/raid/ips/ips_pci.c:207",
    "sys/dev/raid/ips/ips_pci.c:218",
    "sys/dev/raid/ips/ips.c:529",
    "sys/dev/raid/ips/ips.c:531",
    "sys/dev/raid/ips/ips.c:533"
  ],
  "poc_changes": "n/a - seed sketch could not run at all: the guest lacks ServeRAID hardware, so no ips device instance ever exists; trigger.sh encodes the hardware-gated sequence instead",
  "attempts": 1,
  "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": 25,
  "guest_dirty": 0,
  "build_cmd": "none",
  "run_cmd": "sh findings/poc/DF-5115/trigger.sh",
  "code_hash": "32ceac337ccb6a68e7d76562a50689cb41af673a5abaa45be707ba0c188ce271",
  "notes": "status untested (not not_testable/skipped) per orchestrator enum. Guest was checked live: kldload ips succeeds, probe never matches, /dev/ips* absent. sc->configured is referenced ONLY inside ips_pci.c (rg-verified), so the fix is purely local. Distinct from DF-5025 (ipsd open/detach TOCTOU on ips_disk.c) and DF-4613/4614/4640 (ips.c/ips_commands.c lifecycle).",
  "recommended_fix": "Move sc->configured = 0 to after the ips_adapter_free EBUSY check in ips_pci_detach so a failed detach leaves the state machine intact for shutdown flushing and a full unwind on retry.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": false,
  "fix_patched_reproduced": false,
  "fix_verdict": "fix.diff is a 2-line move authored against the read-only sys/ tree after static verification; it cannot be build-validated on this guest because the buggy path needs ServeRAID hardware to even instantiate the driver. The patch keeps configured=1 on EBUSY, restoring correct shutdown flush and full unwind on retried detach.",
  "fix_evidence": "fix.diff; ips_pci.c:202-208 before/after shown in VERDICT.md"
}