⬢ DragonFlyBSD Kernel Audit
DF-4174 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4174",
  "status": "untested",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Bug certain from code trace; PoC built and executed to the hardware gate. gdtexecuteccb copies nseg physical S/G entries verbatim into the fixed 32-entry (GDT_MAXSG) array at the tail of the 324-byte gccb->gc_cmd (iir.c:1271-1284 raw, 1255-1269 cache) with no bound on nseg; the CAM_SCATTER_VALID|CAM_SG_LIST_PHYS branch of gdt_raw_cmd/gdt_cache_cmd (iir.c:876-877, 983-984) takes sglist_cnt straight from the CCB, so a pass(4) caller (root-only, /dev/passN mode 0600) sending sglist_cnt=64 overflows ~256 bytes into the adjacent struct gdt_ccb fields of the kmallocd sc_gccbs block. On this guest the PoC compiled cleanly (build.log BUILD_RC=0) and ran to the SIM check: /dev/pass0 sits on SIM ata, so the trigger cannot be delivered (run.log, exit 4); no iir controller exists (gate_check.log).",
  "exploit_chain": "",
  "evidence": "run.log (SIM check trips: SIM is not \"iir\", exit 4); build.log (BUILD_RC=0); VERDICT.md (path:line trace); fix.diff (git apply --check clean)",
  "kernel_refs": [
    "sys/dev/raid/iir/iir.c:871",
    "sys/dev/raid/iir/iir.c:876",
    "sys/dev/raid/iir/iir.c:983",
    "sys/dev/raid/iir/iir.c:1254",
    "sys/dev/raid/iir/iir.c:1271",
    "sys/dev/raid/iir/iir.c:1283",
    "sys/dev/raid/iir/iir.h:71",
    "sys/dev/raid/iir/iir.h:243"
  ],
  "poc_changes": "rewrote seed against DragonFly camlib: no cam_fill_csio (manual CCB fill), cam_open_btl takes path_id_t not a bus-name string (open pass device + XPT_PATH_INQ cpi.dev_name check instead), dropped MSG_SIMPLE_Q_TAG/SSD_FULL_LEN, local 16-byte {addr,len} struct for userland bus_dma_segment",
  "attempts": 3,
  "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": "cc -O -Wall -o sg_overflow sg_overflow.c -lcam",
  "run_cmd": "./sg_overflow /dev/pass0",
  "code_hash": "4a8be2b55380c243754c9e4baa938c8b1fb87ce52c488a9a44e0bb3b624f16d7",
  "notes": "Root-gated (pass device 0600) and hardware-gated (needs iir SIM) -> Low severity, memcorrupt bucket. Guest artifacts (/root/sg_overflow*) removed after capture; guest left clean and up.",
  "recommended_fix": "Reject physical S/G lists with sglist_cnt > GDT_MAXSG in gdt_next before dispatch, mirroring the existing cdb_len > 12 rejection (see fix.diff)",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff adds the GDT_MAXSG rejection in gdt_next and passes git apply --check; runtime validation requires an iir bus",
  "fix_evidence": "findings/poc/DF-4174/fix.diff (git apply --check clean)"
}