{
  "finding_id": "DF-4279",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "REPRODUCED: CCDIOCSET accepts a negative interleave (signed int, no kernel-side lower-bound validation at ccd.c:1326; ccdconfig(8) rejects it but the raw ioctl does not). The negative ileave reaches ccdbuffer() where cbc=dbtob(ileave-cboff) is negative (ccd.c:1068), producing a negative cb_buf.b_bcount (ccd.c:1071); ccdstart() then grows bcount by |rcount| each iteration (ccd.c:886-888) and walks b_data backwards out of the user buffer, issuing unbounded negative-length device transfers that fault in memmove -> vm_fault NULL-object assertion -> kernel panic. Two identical panics on the stock kernel; with fix.diff hunk 1 (reject ileave<0) the ioctl returns EINVAL, no panic, control path unregressed.",
  "exploit_chain": "root/operator user -> open /dev/ccdN (0640 root:operator) -> ioctl(CCDIOCSET, ileave=-1, CCD-typed component) -> pread 512 bytes -> negative b_bcount + backward b_data walk in ccdstart -> OOB transfer -> kernel panic (un-killable spin precedes the crash). No uid0 chain; class is privileged local DoS/panic.",
  "evidence": "panic.txt (full serial-console panic: assertion obj != NULL failed in vm_object_hold_shared, memmove fault); run.2.log (serial sequence: control config ok, ileave=-1 config accepted, immediate panic); README.md/run.sh (self-contained reproduce); fix_patched.log (patched module: ileave=-1 -> CCDIOCSET: Invalid argument, ileave=32 control still works, guest survives); build.log (kernel+module rebuild, RC=0)",
  "kernel_refs": [
    "sys/dev/disk/ccd/ccd.c:1326",
    "sys/dev/disk/ccd/ccd.c:484",
    "sys/dev/disk/ccd/ccd.c:514",
    "sys/dev/disk/ccd/ccd.c:975",
    "sys/dev/disk/ccd/ccd.c:1068",
    "sys/dev/disk/ccd/ccd.c:1071",
    "sys/dev/disk/ccd/ccd.c:886",
    "sys/dev/disk/ccd/ccd.c:888"
  ],
  "poc_changes": "Seed sketch was author-authored here: raw CCDIOCSET trigger with _KERNEL_STRUCTURES include fix (ccdvar.h is not userland-includable otherwise), vn(4)+disklabel32 fstype=ccd component setup (no mdconfig on guest), positive control included.",
  "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": "cc -O -o /tmp/df4279 /root/df4279/trigger.c",
  "run_cmd": "sh /root/df4279/run.sh   (kldload ccd; vnconfig + disklabel32 fstype=ccd; control ileave=32; trigger ileave=-1)",
  "code_hash": "a75a4c169b746e8f4df0800fc2b475139b138aa8b9ed980e2e128cc16cce0d94",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff hunk 1 (reject ccio_ileave<0 in CCDIOCSET) validated on the guest: ccd.c rebuilt as a module from patched /usr/src, installed, ileave=-1 now returns EINVAL and the previously-guaranteed panic is gone across repeated runs while the ileave=32 control path is unregressed. Hunk 2 (DF-4280 guard) validated in the same build.",
  "fix_evidence": "findings/poc/DF-4279/fix_patched.log (patched: CCDIOCSET: Invalid argument + guest survives + uptime shown; baseline: panic.txt/run.2.log); build.log (nativekernel RC=0 + module link)",
  "notes": "Also observed pre-panic: the reading thread spins un-killably in ccdstart (timeout could not reclaim it) and ccd.c:507 prints stale sc_unit (always ccd0) because sc_unit is assigned at ccd.c:593 after the print. /dev/ccdN perms are 0640 root:operator (subr_disk.c:699-701), so the operator group reaches this without root. Guest restored with vm.sh reset with-src after validation.",
  "recommended_fix": "Validate ccio_ileave >= 0 in CCDIOCSET (return EINVAL) before configuring; optionally make the ileave guards in ccdinit use unsigned math."
}