{
  "finding_id": "DF-2504",
  "status": "reproduced",
  "verdict": "Divide-by-zero CONFIRMED and reproduced on the real kernel via a single userland ioctl on the real /dev/acd0 (empty QEMU DVD-ROM, O_RDONLY, no disc): Fatal trap 18, Stopped at acd_set_ioparm+0x69: divl -- exactly rounddown(iomax,0) at atapi-cd.c:951 after :724 stores the unvalidated user int. Control roundtrip (2352) works; zero panics deterministically; single-fix kernel returns EINVAL and survives (fix validated). IMPORTANT THREAT-MODEL CORRECTION: the unprivileged-operator arm is REFUTED on current master -- opening /dev/acd0 (or /dev/cd0, or any raw disk device) requires SYSCAP_RESTRICTEDROOT (diskopen, sys/kern/subr_disk.c:1070-1073; EPERM demonstrated for operator-group user in unpriv_open_test.log), so the panic is only reachable by root/RESTRICTEDROOT principals. Effective severity: Low (privileged-user deterministic panic), not the filed Medium unpriv DoS.",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "exploit_chain": "root/RESTRICTEDROOT: open(/dev/acd0, O_RDONLY) -> ioctl(CDRIOCSETBLOCKSIZE, 0) -> acd_ioctl atapi-cd.c:724 (no validation, no priv check) -> acd_set_ioparm :951 rounddown(65534, 0) -> fatal trap 18 -> kernel panic (DoS). No escalation: the primitive is a deterministic crash with fully controlled divisor sign/zero but no memory-safety impact.",
  "evidence": "panic.txt (Fatal trap 18 ... Stopped at acd_set_ioparm+0x69: divl %ecx,%eax from serial console); run.log (control 2352 ok + fatal run transcript); unpriv_open_test.log (operator-group EPERM at open on /dev/acd0, /dev/cd0, /dev/serno -- RESTRICTEDROOT gate); fix_run.log (patched kernel: EINVAL, survives).",
  "kernel_refs": [
    "sys/dev/disk/nata/atapi-cd.c:723-726",
    "sys/dev/disk/nata/atapi-cd.c:951",
    "sys/sys/param.h:400",
    "sys/kern/subr_disk.c:1070-1073",
    "sys/sys/cdrio.h:109"
  ],
  "poc_changes": "Seed PoC sketch (none existed in the pack) rewritten as findings/poc/DF-2504/poc_setblocksize.c: correct CDRIOCSETBLOCKSIZE = _IOW(c,110,int) from sys/sys/cdrio.h, O_RDONLY open, control subcommand (2352 + CDRIOCGETBLOCKSIZE roundtrip) before the fatal 0 run.",
  "attempts": 4,
  "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": 1500,
  "guest_dirty": 0,
  "build_cmd": "cc -O -Wall -o poc_setblocksize poc_setblocksize.c",
  "run_cmd": "./poc_setblocksize /dev/acd0 2352   # control\n./poc_setblocksize /dev/acd0          # fatal: CDRIOCSETBLOCKSIZE(0)",
  "code_hash": "2ccd941d918c04b360a51315a02a3bf9cb05218e2728c6852255b1966f37b7f4",
  "notes": "Guest left clean: disk reverted to with-src snapshot and booted after validation. Related hardening observation (not filed): CDRIOCSETBLOCKSIZE also accepts negative and huge block sizes (rounddown math defined but si_iosize_max/si_bsize_phys nonsense); a range check (2048/2352 like acd_strategys switch) would be the thorough fix. No memory-corruption class here (divide trap only), so no exploit development beyond the panic per contract; uid0 route not applicable.",
  "recommended_fix": "In acd_ioctls CDRIOCSETBLOCKSIZE case reject non-positive (ideally non-2048/2352) block sizes with EINVAL before storing and calling acd_set_ioparm.",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fixed",
  "fix_evidence": "fix_run.log: patched kernel #1 (Thu Oct 15 23:37:29 UTC 2026) -- control 2352 ok; CDRIOCSETBLOCKSIZE(0) returns Invalid argument (EINVAL), no trap, guest up. Baseline (kernel #0): same ioctl -> Fatal trap 18 at acd_set_ioparm+0x69 (panic.txt). 1/1 baseline panic vs 0/1 patched. fix.diff (EINVAL on <=0) applied to guest /usr/src only; audit sys/ tree untouched.",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #1: Thu Oct 15 23:37:29 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64"
}