⬢ DragonFlyBSD Kernel Audit
DF-2273 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2273",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "The unbounded strlen at scsi_ch.c:1300 reproduces exactly as claimed: with no NUL in the 33-byte cv_volid the scan ran 36 bytes, past the field through cv_serial and padding into adjacent bytes of the kernel stack copy (interposed counting shim, strlen_over33=1 strlen_max=36), while the retained ssvtp.vitf copy stayed bounded at 32 data bytes plus space padding (svt_vitf_nonspace=32) — a scan-only over-read with nothing retained. Containment established: DragonFlys ioctl layer copyins the csvr once into a kernel stack buffer (sys_generic.c:685 -> :724), so the walk cannot reach user memory or unmapped pages; the page-boundary/PROT_NONE experiment completed with no fault. The strnlen bound (fix.diff) caps the scan at 33 on the fixed kernel (strnlen_max=33, strlen_calls=0) with identical retained output. Info severity stands; no security impact beyond hardening.",
  "exploit_chain": "",
  "evidence": "voltag_baseline.log (strlen_over33=1 strlen_max=36 svt_vitf_nonspace=32), voltag_fixed.log (strnlen_calls=5 strnlen_max=33 strlen_calls=0), boundary lines in both logs (clean SUCCESS, no fault), rig df_post.c dfh_strlen/dfh_strnlen instrumentation",
  "kernel_refs": ["sys/bus/cam/scsi/scsi_ch.c:1300", "sys/bus/cam/scsi/scsi_ch.c:1301", "sys/sys/chio.h:133", "sys/bus/cam/scsi/scsi_ch.h:299", "sys/kern/sys_generic.c:685", "sys/kern/sys_generic.c:724"],
  "poc_changes": "No seed existed; wrote ch_user.c vt/boundary subcommands plus the dfh_strlen/dfh_strnlen counting interposition in the harness postamble.",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT x86_64 (baseline kernel #2 Sun Oct 18 00:11:42; fixed kernel #1 Sun Oct 18 00:24:51)",
  "runtime_sec": 300,
  "guest_dirty": 0,
  "build_cmd": "see ../DF-2270/rig/build.sh (shared harness kernel)",
  "run_cmd": "vm.sh run_root /root/ch_user vt 0|5|32|none|far|boundary; vm.sh run_root sysctl debug.dfch.stats",
  "code_hash": "0b7d48862ca46ac581c954486df7c4a0b9bef6ce7c409b371917ef0c61ccf4fa",
  "notes": "Scan stop at exactly 33 when the struct padding is zero (vt none/far use memset-0 structs); the 36-byte walk required a fully nonzero struct (boundary case). Adjacent bytes are kernel stack, not attacker content; nothing is disclosed.",
  "recommended_fix": "Bound the scan: replace strlen with strnlen(cv_volid, sizeof(cv_volid)) in the min() at scsi_ch.c:1300 (fix.diff)"
}