⬢ DragonFlyBSD Kernel Audit
DF-2429 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2429",
  "status": "reproduced",
  "verdict": "REPRODUCED: production btaction XPT_CALC_GEOMETRY handler panics the kernel (Fatal trap 18 integer divide fault at btaction+0x4ff, the bt.c:1157 size_mb division) when xpt_action delivers block_size=2MiB (device-fed READ CAPACITY value that passes the CAM-layer block_size==0/volume_size==0 filter at cam_xpt.c:3063-3071). Honest correction: the block_size==0 variant cited first in the finding never reaches bt.c -- the CAM filter completes it with CAM_REQ_CMP (demonstrated live); only the >1MiB variant (inner quotient 0) panics. Local DoS/panic from hostile SCSI target data on real bt(4) hardware.",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "exploit_chain": "lying SCSI target reports secsize>1MiB in READ CAPACITY -> da(4) dasetgeom -> xpt_action(XPT_CALC_GEOMETRY) (filter passes, both fields nonzero) -> production btaction bt.c:1157 computes (1024*1024)/2097152==0 then volume_size/0 -> #DE -> kernel panic",
  "evidence": "panic.txt (Fatal trap 18, Stopped at btaction+0x4ff: divq %rsi,%eax; disassembly context in VERDICT.md); run.log (variant 1 block_size=0 survives with heads=0 status=0x1 proving the CAM filter; variant 2 panics)",
  "kernel_refs": [
    "sys/dev/disk/buslogic/bt.c:1157",
    "sys/bus/cam/cam_xpt.c:3063",
    "sys/bus/cam/scsi/scsi_da.c:1831",
    "sys/bus/cam/scsi/scsi_da.c:2302"
  ],
  "poc_changes": "original finding cited block_size==0 as the trigger; the CAM layer filters that case (proven live), so the PoC uses block_size=2097152 (>1MiB) which zeroes the inner quotient -- same division, same line, actually reachable",
  "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": 95,
  "guest_dirty": 0,
  "build_cmd": "./push_rig.sh (make KERNBUILDDIR=/usr/obj/usr/src/sys/X86_64_GENERIC; cc dfbt_ctl.c)",
  "run_cmd": "sh run.sh  (dfbt_ctl calcgeom 0 4194304; dfbt_ctl calcgeom 2097152 4194304)",
  "code_hash": "745f8b43787e6bb6a37f62b8ac9fc1a99d7aab498a1faa6d34c8caeba4ba8651",
  "notes": "bt(4) is compiled into X86_64_GENERIC (config line 102); no BusLogic HBA exists on the QEMU guest, so the rig fabricates the post-attach softc and dispatches the REAL production handlers resolved from /boot/kernel/kernel (no KASLR, prologues byte-verified). Guest reset clean after the panic run.",
  "recommended_fix": "Reject block_size==0 or >1MiB with CAM_REQ_INVALID before the division (fix.diff, object-compile validated under -Werror with kernel headers)",
  "fix_status": "not_tested",
  "fix_baseline_reproduced": true,
  "fix_patched_reproduced": false,
  "fix_verdict": "object-compile validation only (panic class, not memory corruption; kernel A/B not mandated): patched bt.c+btreg.h compile clean with the X86_64_GENERIC kernel flags",
  "fix_evidence": "fix.diff; guest build log line FIXED-COMPILES-CLEAN with bt.fixed.o produced (cc -Werror, kernel headers)"
}