# DF-1116 — Integer divide-by-zero in fwdma_malloc_multiseg (FireWire)

## Finding
`fwdma_malloc_multiseg` at `sys/bus/firewire/fwdma.c:159` computes
`ssize = rounddown(PAGE_SIZE, esize)` which expands to
`(PAGE_SIZE / esize) * esize` (`sys/sys/param.h:400`). With `esize == 0`
this is integer divide-by-zero → kernel `#DE` trap → panic at
`sys/platform/pc64/x86_64/trap.c:1101`.

`esize` is `b->psize` passed from `fwdev_allocbuf` (`sys/bus/firewire/fwdev.c:108`)
after `roundup2(b->psize, 4)` which is identity for 0 (`fwdev.c:107`).
`psize = 0` is user-supplied via the unchecked `FW_SSTBUF` ioctl
(`fwdev.c:504-506` `bcopy(ibufreq, &d->bufreq, ...)`).

Trigger path: `FW_STSTREAM` / `FW_SRSTREAM` → `fwdev_allocbuf` →
`fwdma_malloc_multiseg(esize=0)` → `#DE`.

## Reachability on this guest
**NOT reachable.** The FireWire driver (`firewire.ko`) is loadable but no
FireWire controller is present in the QEMU guest (`pciconf -lv` shows no
1394 OHCI device), so the driver never attaches and `/dev/fwN.M` is never
created. The bug is real and deterministic but latent on this host.

A userspace harness reproduces the arithmetic primitive (SIGFPE = the
user-mode analogue of kernel `#DE`).

## Build / Run / Expected
```
cc -O2 -o harness harness.c     # build.sh
./harness                        # run.sh
# Expected: "SIGFPE: integer divide by zero -- primitive reproduced."
```

## Files
- `harness.c` — standalone reproduction of the div-by-zero arithmetic.
- `fix.diff` — adds `if (esize <= 0 || n <= 0) return (NULL);` at
  `fwdma_malloc_multiseg` + defense-in-depth check in `fwdev_allocbuf`.
- `build.log` / `run.log` / `env.txt` — captured outputs.
