⬢ DragonFlyBSD Kernel Audit
DF-2303 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-2303",
  "status": "not_reproduced",
  "reproduced": 0,
  "impact": "corruption",
  "confidence": "certain",
  "verdict": "The negative-length bcopy at fwohci.c:2735 is NOT reachable from packet input on this tree, and the battery proves it mechanically: every header straddle the real fwohci_arcv stream parser can produce (quadlet-aligned F in {4,8,12} for 16-byte headers, {4,8} for 12-byte headers on a 4096-byte buffer) was driven through the real split-header path with firewire_debug on - the real code printed rlen=4/8/12 with offset=-X for every case, rlen_new = 16-rlen_old stayed in [4,12], no why rlen < 0, reassembly completed, guest stable. Invariant (line-accurate): buf_offset goes negative only at fwohci.c:2762 after arcv_swap returns -hlen; if resCount!=0 the overwrite at fwohci.c:2871 discards the split state first, so the branch is only entered with resCount==0 where rlen_old = psize - X = len at the failed parse, and the parse failed precisely because hlen > len with hlen <= 16; additionally arcv_swap has no STREAM case and AR packet boundaries are quadlet multiples, so F is quadlet-aligned. rlen_old > 16 is therefore impossible. The landmine itself is real: injecting the impossible state (buf_offset=-4072, rlen_old=24) made the real code print why rlen < 0 and the very next bcopy hit the stack guard page - panic: vm_fault: fault on stack guard (memmove in trace) - a live stack-smash primitive if control flow ever changes (panic.txt). Verdict as filed: latent, unreachable today; the hardening guard is recommended and validated.",
  "exploit_chain": "none from packet input (proven); state injection only: rig sets dbch->buf_offset beyond any parser-producible value -> real bcopy(db_tr->buf, p, (size_t)-8) -> stack guard page fault -> panic",
  "evidence": "run.log: battery F=4/8/12 (tcode WREQB) and F=4/8 (tcode WRES) with the real-code rlen=/offset=/split header console lines, guest up after all; run2303b.log + panic.txt: injected state -> why rlen < 0 -> panic vm_fault fault on stack guard, memmove backtrace; run_fixed.log: same injection on patched kernel prints oversized header fragment, drop and survives",
  "kernel_refs": ["sys/bus/firewire/fwohci.c:2699", "sys/bus/firewire/fwohci.c:2712", "sys/bus/firewire/fwohci.c:2729", "sys/bus/firewire/fwohci.c:2732", "sys/bus/firewire/fwohci.c:2733", "sys/bus/firewire/fwohci.c:2735", "sys/bus/firewire/fwohci.c:2756", "sys/bus/firewire/fwohci.c:2762", "sys/bus/firewire/fwohci.c:2871", "sys/bus/firewire/fwohci.c:2578"],
  "poc_changes": "Rig FWOIOC_ARCV: real fwohci_db_init + real fwohci_rx_enable + real fwohci_add_rx_buf allocate the AR channel; received-DMA state fabricated exactly as OHCI AR DMA leaves it (quadlet-aligned WRES(16B)/WREQB(20B) filler chain, split header at X=psize-F, resCount/status in desc.res); natural mode runs the real fwohci_arcv; inject mode forces an impossible buf_offset. First battery attempt used STREAM fillers - disproven: arcv_swap rejects tcode 0xa (Unknown tcode 10) and STREAM never reaches the split path; replaced with quadlet-aligned WRES/WREQB chains.",
  "attempts": 4,
  "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": 900,
  "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/run2303.sh (battery) ; sh /root/fwo/run2303b.sh (state injection, panics)",
  "code_hash": "32c9c567b4185994d7189b0afb68d72d9d4a3d1c02bdd62424d762a660ee24fd",
  "notes": "Impact field reflects the code-defect class (demonstrated memory corruption via injection); no attacker-reachable input produces it on this tree. Related latent correctness bug noted for maintainers: the fwohci.c:2871 overwrite silently discards a legitimate split-header state whenever resCount!=0 (fragmented AR buffers lose reassembly state); out of scope of this finding.",
  "recommended_fix": "Turn the rlen<0 diagnostic into a guard: drop the packet and goto out instead of falling into bcopy (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 impossible-state injection prints fwohci_arcv: oversized header fragment, drop and survives with no panic (run_fixed.log); the natural battery behavior is unchanged (reachable path never takes the guard).",
  "fix_evidence": "run_fixed.log DF-2303 section: CTL_ARCV mode=1 inj=4072 returns, dmesg shows oversized header fragment drop, uptime continuous"
}