# DF-2303 VERDICT — latent negative-length bcopy in fwohci_arcv

* finding: DF-2303, fwohci.c:2729-2735 (split-header pullup,
  rlen = sizeof(pktbuf) - rlen; unguarded bcopy with negative len)
* status: **not_reproduced** (from packet input; proven unreachable)
* impact class: corruption (the code defect is a live stack-smash
  primitive — demonstrated by state injection — but no attacker-
  reachable input produces the state on this tree)
* confidence: certain (as a negative result)

## (A) Battery — the complete reachable split-header space
Rig: REAL fwohci_db_init + REAL fwohci_rx_enable on arrq (psize=4096,
ndesc=1, ndb=128; per-tr buffers allocated by the real
fwohci_add_rx_buf), received-DMA state fabricated exactly as OHCI AR
DMA would leave it (quadlet-aligned WRES(16B)/WREQB(20B) filler chain
up to X, split packet-B header at X = psize - F, resCount/status in
desc.res), then REAL fwohci_arcv(sc, dbch, -1) with firewire_debug=1.

Observed from the real code (console/dmesg, run.log):
```
FWOH: ARCV NATURAL tcode=1 hdr=16 F=4  X=4092 -> REAL fwohci_arcv
split header
rlen=4, offset=-4092
... F=8: rlen=8, offset=-4088 ... F=12: rlen=12, offset=-4084
WRES F=4: rlen=4, offset=-4092 ... F=8: rlen=8, offset=-4088
```
rlen_new = 16 - rlen_old in [4,12] — strictly positive; reassembly
completed for every case (buf_offset positive after, pdb_tr cleared);
no "why rlen < 0"; guest stable after all runs.

Why this is the COMPLETE set: quadlet alignment (packet boundaries are
multiples of 4) + headers of 12/16 bytes + hlen>len split criterion +
the resCount==0 requirement implied by the 2871 clobber (see README)
=> F in {4,8,12} for 16-byte headers, {4,8} for 12-byte headers.
An earlier battery variant that tried STREAM fillers proved
arcv_swap rejects tcode 0xa outright ("Unknown tcode 10",
fwohci.c:2614-2618) — STREAM never reaches the split path at all.

## (B) Injection — the landmine is real
`fwpoc ctl arcv 1 0 0 4072` sets dbch->buf_offset = -4072
(rlen_old = 24 > 16 — impossible per (A)) and calls the real
fwohci_arcv:
```
FWOH: ARCV INJECT buf_offset=-4072 -> rlen_old=24 (EXCEEDS 16)
why rlen < 0                                   <- fwohci.c:2734
panic: vm_fault: fault on stack guard, addr: 0xfffff80116b51000
memmove() at memmove+0x24f <- fwoctl_ioctl (fwohci_arcv inlined)
```
(panic.txt) — first bcopy overflows pktbuf[16] on the stack, second
bcopy receives (size_t)-8 and writes until the stack guard page:
catastrophic kernel memory corruption IF the state is ever reachable.

## Bottom line
The filed claim is exactly confirmed: the code is a latent landmine
("developer comment shows awareness without understanding
consequence") that is unreachable from packet input on this tree.
Recommend the one-line guard anyway (defense in depth; any future
change to the 2871 clobber or to busdma resCount semantics re-arms
it), plus note that the 2871 overwrite itself silently discards a
legitimate split-header state (separate correctness bug, out of
scope of this finding).

## Fix validation (A/B)
fix.diff: `if (rlen < 0) { kprintf drop; pdb_tr=NULL; buf_offset=0;
goto out; }`. Fixed kernel + identical injection: drop message
printed, NO panic, guest up (run_fixed.log).

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
