โฌข DragonFlyBSD Kernel Audit
DF-3898 / verdict.json
โ† back to finding โ†“ download raw
{
  "finding_id": "DF-3898",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "none",
  "confidence": "likely",
  "verdict": "mps_detach_sas waits at most 30 seconds for the rescan thread (lksleep ... 30*hz, mps_sas.c:825-826) and then unconditionally frees sassc->targets and sassc (mps_sas.c:831-832) โ€” after cam_sim_free already ran (mps_sas.c:815-818) โ€” even though mpssas_scanner_thread only observes MPSSAS_SHUTDOWN after its current xpt_action returns, and a single XPT_SCAN_BUS leg over wedged targets (60 s CCB timeouts with retries, cf. mps_sas.c:3128-3130) can far exceed 30 s. The still-running thread then uses the freed sim/sassc (mpssas_action via cam_sim_softc, TAILQ_REMOVE on ccb_scanq at mps_sas.c:2906-2911) and performs freed-memory writes on exit (sassc->flags &= ~MPSSAS_SCANTHREAD at mps_sas.c:2919) โ€” use-after-free. Trigger needs a privileged detach/kldunload racing a stuck bus scan on real hardware. Not reproduced: no SAS2 HBA in the guest; lifetime sequence certain from source.",
  "exploit_chain": "",
  "evidence": "VERDICT.md (path:line proof of bounded wait vs unbounded scan leg), env.txt, run.sh + run.log (hardware gate), fix.diff (leak-not-UAF guard)",
  "kernel_refs": [
    "sys/dev/raid/mps/mps_sas.c:820",
    "sys/dev/raid/mps/mps_sas.c:825",
    "sys/dev/raid/mps/mps_sas.c:831",
    "sys/dev/raid/mps/mps_sas.c:815",
    "sys/dev/raid/mps/mps_sas.c:2897",
    "sys/dev/raid/mps/mps_sas.c:2919"
  ],
  "poc_changes": "n/a โ€” privileged detach + hardware-gated.",
  "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": 15,
  "guest_dirty": 0,
  "build_cmd": "n/a",
  "run_cmd": "sh findings/poc/DF-3898/run.sh",
  "code_hash": "",
  "notes": "Pass-2 lifetime/error-path target: bounded-wait-then-free is the classic detach UAF shape. Upstream FreeBSD mps(4) detach differs (no scanner kthread), so this is DragonFly-port-specific.",
  "recommended_fix": "If MPSSAS_SCANTHREAD is still set after the bounded sleep, warn and leak sassc instead of freeing it under the live thread; longer term make the thread wait unbounded.",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff converts the overrun into a warned leak; cannot be exercised on this guest (no SAS2 HBA).",
  "fix_evidence": "findings/poc/DF-3898/fix.diff"
}