# DF-2295 — fw_read iso path over-read (stream.len unbounded vs psize)

## Verdict (short)
REPRODUCED with full byte attribution on the stock `fwdev.o` +
`fwdma.o` binaries:

* Operator-group user sets up a legal iso receive stream
  (FW_SSTBUF rx=4chunk/8packet/512psize, FW_SRSTREAM ch=1) — the DMA
  ring is allocated by the real `fwdma_malloc_multiseg`.
* The harness emulates the malicious FireWire peer: it fills every
  slot of the real DMA ring with 16-byte canary records
  [magic|slot|offset|xor] and writes a received stream-packet header
  with `stream.len = 1500` into slot 0 (exactly what OHCI DMA would
  store; the peer controls `len`).
* The user `read(2)s` 1504 bytes. Stock kernel:
  `uiomove(fp, fp->mode.stream.len + 4, uio)` (fwdev.c:329-330) copies
  **1504 bytes out of a 512-byte packet slot — 992 bytes beyond the
  slot — into userspace, returning 0** (no error).
* Every 16-byte window of the beyond-slot region decodes to the exact
  expected (slot, offset) pair: user[512..1504] == ring slots 1..3
  content. Host-side verification of leak_sample.txt: 62/62 windows
  attributed (leak_attributed.txt).

Fix validated: clamping the copy to `ir->psize` keeps the legit packet
(len=508) bit-identical (leak_legit_508.txt == leak_fixed_508.txt) and
turns the malicious packet into per-slot truncated copies.

## Threat model / reachability honesty
* Requires (a) an open /dev/fwU.S by an operator-group user and (b) a
  malicious FireWire peer transmitting an iso stream packet whose
  header `len` exceeds psize-4 (physical/bus-attached attacker or
  compromised device). The header quadlet is DMA'd by hardware into the
  packet slot and is never validated against the slot size.
* Local-only exploitation without a peer is NOT possible: the user
  cannot place a forged header into the ring (hardware writes it).
* Disclosure target: bytes following the packet slot inside the
  bus_dmamem ring segment(s), and — for large len (16-bit field, up to
  65535) — up to ~64KB past the slot, i.e. past the whole ring
  allocation into adjacent kernel KVA. The attributed 992-byte
  over-read (ring slots 1-3) is proven; the beyond-ring variant was
  not separately demonstrated (kernel already rebuilt with the fix for
  A/B; same primitive).

## Files
* poc_2295.c — trigger (setup, read, attribution, leak_sample.txt)
* fwhctl.c — root-side peer emulation (inject canary ring + packet)
* leak_sample.txt — the 1504-byte read dump (baseline, malicious len)
* leak_attributed.txt — host-side byte-attribution proof (62/62)
* leak_legit_508.txt / leak_fixed_508.txt — A/B bit-identity
* run_2295_baseline.log, run_2295_fixed_malicious.log,
  run_2295_fixed_legit.log
* fix.diff — combined fix (this finding: clamp ulen to ir->psize)
