# VERDICT — DF-1116

## Verdict: REPRODUCED (primitive) / NOT REACHABLE on guest (HW-gated)

The cited bug is **real and confirmed** by source trace + userspace
arithmetic reproduction. It is a **latent** kernel-panic primitive:
reachable only when a FireWire controller is attached, which this audit
guest does not have.

## Mechanism (confirmed path:line)
1. `FW_SSTBUF` ioctl (`sys/bus/firewire/fwdev.c:504-506`): user-supplied
   `ibufreq` is `bcopy`'d into `d->bufreq` with **no validation** of
   `psize`/`nchunk`/`npacket`. A local user in group `operator` (device
   perms `0660 root:operator` per `fwdev.c:173-175`) can set `psize = 0`.
2. `FW_STSTREAM` / `FW_SRSTREAM` (`fwdev.c:447` / `:475`) →
   `fwdev_allocbuf(fc, ir/it, &d->bufreq.tx/rx)`.
3. `fwdev_allocbuf` (`fwdev.c:107`): `b->psize = roundup2(b->psize, 4)` —
   identity for 0. Passes `b->psize` as `esize` to
   `fwdma_malloc_multiseg` (`fwdev.c:108-109`).
4. `fwdma_malloc_multiseg` (`fwdma.c:159`):
   `ssize = rounddown(PAGE_SIZE, esize)` → `(4096 / 0) * 0` → **#DE trap**.
5. Trap → panic at `sys/platform/pc64/x86_64/trap.c:1101`.

No `priv_check` on the ioctl path; only file-permission gating.

## Reproduction (userspace harness)
The harness reproduces the arithmetic primitive in userspace. `volatile`
defeats constant-folding (div-by-zero is UB; gcc would fold it at `-O2`
without this). On x86, integer div-by-zero raises `SIGFPE` (the user-mode
analogue of kernel `#DE`):
```
SIGFPE: integer divide by zero -- primitive reproduced.
In kernel context this is a #DE trap -> panic (trap.c:1101).
```

## Impact ceiling
- **Per-call**: deterministic kernel panic (DoS). Single-threaded, 100%
  reproducible. No memory-corruption primitive — the trap fires before any
  write completes.
- **Privilege boundary**: `operator` group → kernel panic. Not unpriv→root;
  not even unpriv→DoS unless the user is in `operator` or the device is
  world-writable.
- **Realistic**: requires a FireWire controller attached. Modern systems
  rarely have FW; legacy/scientific imaging setups do.

## Fix
`fix.diff` adds two guards:
1. `fwdma_malloc_multiseg` (`fwdma.c`): `if (esize <= 0 || n <= 0) return (NULL);`
   at the top — rejects the degenerate request before the divide.
2. `fwdev_allocbuf` (`fwdev.c`): `if (b->psize == 0 || b->nchunk == 0 || b->npacket == 0) return (EINVAL);`
   — defense-in-depth at the caller.

Validated: `firewire.ko` builds with `rc=0` after applying the fix.

## Fix validation
- Patch applies cleanly: `Hunk #1 succeeded at 150` (fwdma.c) + `Hunk #1 succeeded at 105` (fwdev.c).
- `make` in `sys/bus/firewire/` → `firewire.ko` linked, `RC=0`.
- Cannot boot-test the fix (no FireWire HW on guest); `fix_status: not_testable`
  per the HW-gated allowance. The fix compiles and is a trivial guard.

## PoC changes
- `harness.c` written from scratch (no prior PoC). Reproduces the
  arithmetic primitive; `volatile` prevents the compiler from eliding the
  div-by-zero.
