⬢ DragonFlyBSD Kernel Audit
DF-2523 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2523",
  "status": "reproduced",
  "reproduced": true,
  "impact": "dos",
  "confidence": "certain",
  "verdict": "Reproduced with the production handler: dispatched the real trm_Interrupt() of kldloadd /boot/kernel/trm.ko with INT_RESELECTED and TRMREG_SCSI_TARGETID=0x1000 (the driver masks the register with 0x1FFF at trm.c:2426, but a DCB can only pack to (LUN<<8)|ID <= 0x070F - any reselection with stray high bits is unmatchable by construction). The production DCB ring walk at trm.c:2428-2431 (circular list, no bound, no escape) never returned: a dedicated kernel thread sat inside it through 3s/6s/9s heartbeat checkpoints, and the guest then wedged completely - ssh stopped answering, the serial console went dead, no panic was printed, and recovery required killing QEMU. On real hardware the loop runs in the interrupt handler at crit priority and hard-locks the CPU outright. Control dispatch (matching ID 0x0203) returns through the identical production path, isolating the no-match loop as the sole differential. The bounded-walk fix (DeviceCnt-bounded search + drop-connection recovery on miss) returns immediately on a rebuilt module.",
  "exploit_chain": "DoS primitive only (non-terminating interrupt-context loop => unrecoverable machine lockup); no escalation path.",
  "evidence": "run.log (full serial): df2523[T1] dispatch lines + three df2523[HB]: *** NON-TERMINATION CONFIRMED ... no exit *** markers at 3/6/9s, no RETURNED marker, guest subsequently unresponsive (vm.sh down reported guest not answering (likely DDB on panic); killing qemu); run.patched.log: df2523[T1]: trm_Interrupt RETURNED (unreachable on vulnerable kernel) with no heartbeat, guest healthy.",
  "kernel_refs": [
    "sys/dev/disk/trm/trm.c:2426",
    "sys/dev/disk/trm/trm.c:2428",
    "sys/dev/disk/trm/trm.c:2431",
    "sys/dev/disk/trm/trm.c:1328"
  ],
  "poc_changes": "No seed PoC existed (empty pack). Built from scratch: production-handler dispatch rig (kldload real trm.ko; trm_Interrupt resolved at kldstat base + nm offset 0x1d40); scenario 5 dispatches in a dedicated kernel thread (df2523_t1) with 3s/6s/9s heartbeat callouts so non-termination is provable before the wedge; matching-ID control (go=4) proves the same production path returns.",
  "attempts": 2,
  "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": 900,
  "guest_dirty": 0,
  "build_cmd": "cd /root/df252x && make -m /usr/src/share/mk   (kldload trm; kldload ./df252x_trm_rig.ko)",
  "run_cmd": "sh run.sh   (sysctl kern.df252x.addr=<base+0x1d40>; go=4 matching-reselect control; go=5 unmatchable reselect - guest wedges)",
  "code_hash": "75af3495eff0b1836d378d698019b7fd7e88c49a36b8c267c8f8ac3cfe6faa70",
  "notes": "Fix validated on a module carrying all three trm fixes (fix.all.diff in the shared build); this scenario dispatches exclusively through the reselect hunk. The fix intentionally avoids DO_RSTSCSI polling (would add a second unbounded register wait). Rig state includes DeviceCnt=3 as production ring bookkeeping (used by the fixs bound).",
  "recommended_fix": "Bound the reselect DCB walk by pACB->DeviceCnt and bail out with bus recovery (STOPDMAXFER + DO_CLRFIFO|DO_HWRESELECT) when no DCB matches.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Rebuilt the driver module from the patched source (same nativekernel build as DF-2522, full log fix_build.log) and re-ran the identical scenario against the patched modules own trm_Interrupt: the unmatchable reselection (0x1000) returns immediately - df2523[T1]: trm_Interrupt RETURNED, no heartbeat markers, guest healthy (uptime answered); the matching control behaves exactly as stock (pActiveDCB=ring[2], TmpSRB abort path armed).",
  "fix_evidence": "run.patched.log: df2523[T1]: ... RETURNED (unreachable on vulnerable kernel) with zero HB markers, vs run.log stock: three NON-TERMINATION markers + total guest wedge requiring QEMU kill."
}