{
  "finding_id": "DF-2301",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "print_db (fwohci.c:2322-2404) driven by an operator-group DUMPDMA(0) through the real fwohci_ioctl/dump_dma/dump_db path printed ndesc+1 = 9 rows for an 8-descriptor block: row i==8 read db[8], one 16-byte struct fwohcidb past the block. Attribution is byte-exact: (a) with the match on element 5, row 8 printed exactly the canary planted in element 6 db[0] (KVA 0xfffff80117c14300, rig KVA peek returns the same cafe0001/11111111/22222222/33333333), and the canary cmd key bits also fired the compounding db[i+1] ST2 read (fwohci.c:2377-2382, printing db[9]); (b) with the match on element 63 (last element of the last 4096-byte fwdma segment), row 8 read at seglast.v_addr+4096 - outside every segment allocation - matching the KVA peek of that address. Output goes to console/dmesg (world-readable): kernel DMA-memory disclosure; latent fault if the read ever lands unmapped.",
  "exploit_chain": "operator-group user -> DUMPDMA(0) on /dev/fw0.0 -> fwohci_ioctl (fwohci.c:371) -> dump_db (max=ndesc, fwohci.c:2311) -> print_db loop i<=max (fwohci.c:2347) reads db[ndesc] (and db[i+1] for ST2 keys) -> 16+ bytes past the descriptor block printed to console/dmesg",
  "evidence": "run.log: two print_db dumps with 9 rows each; element-5 dump row 8 = canary values matching CTL_KREAD of &db[8]; element-63 dump row 8 = values at seg1+4096 matching CTL_KREAD of the same out-of-allocation address; run_fixed.log: patched kernel prints exactly 8 rows, no OOB row",
  "kernel_refs": ["sys/bus/firewire/fwohci.c:2322", "sys/bus/firewire/fwohci.c:2347", "sys/bus/firewire/fwohci.c:2377", "sys/bus/firewire/fwohci.c:2379", "sys/bus/firewire/fwohci.c:2400", "sys/bus/firewire/fwohci.c:2311", "sys/bus/firewire/fwdma.c:145"],
  "poc_changes": "Rig prep (fwohci_harness.c FWOIOC_DBINIT/DESCSET/REGWR/KREAD): real fwohci_db_init on atrq with ndesc=8 ndb=64 (2 fwdma segments, 32 elements each), fabricated INPUT_MORE|KEY_ST3 descriptors that avoid all early-exit conditions so the loop runs to exhaustion, canary in element 6, ATQ command-pointer register set in emulated MMIO so dump_db matches the chosen element; trigger issued by opuser as /home/opuser/fwpoc dumpdma 0.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #4: Sun Oct 18 12:45:22 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/FWO  x86_64",
  "runtime_sec": 600,
  "guest_dirty": 0,
  "build_cmd": "cd /usr/src && make -j6 nativekernel KERNCONF=FWO && make installkernel KERNCONF=FWO (userland: cc -O -Wall -o fwpoc fwpoc.c)",
  "run_cmd": "sh /root/fwo/run2301.sh",
  "code_hash": "32c9c567b4185994d7189b0afb68d72d9d4a3d1c02bdd62424d762a660ee24fd",
  "notes": "Read-only OOB; disclosure surface is console/dmesg, not copyout. Severity Low as filed. The ST2 compounding read (db[i+1] at i==max-1... also covered by the fix guard) was demonstrated live when the canary cmd accidentally carried ST2 key bits.",
  "recommended_fix": "Loop bound i<max plus guard the ST2 immediate print with i+1<max (fix.diff)",
  "fix_status": "fixed",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #4: Sun Oct 18 12:45:22 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/FWO x86_64",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Patched kernel: identical prep and DUMPDMA print exactly ndesc=8 rows with no ninth row, no canary row, and no ST2 compounding line (run_fixed.log). Note the combined fix also gates DUMPDMA behind the privilege check, so the A/B dump was issued by root; opuser DUMPDMA produced no print_db output at all on the patched kernel.",
  "fix_evidence": "run_fixed.log DF-2301 section: opuser DUMPDMA prints nothing (gate), root DUMPDMA prints 8 rows ending at i==7 (aa000007/bb000007) with no further row"
}
