# DF-3581 — VERDICT

**Status: untested.** The trigger is a firmware-written `closed_count`
outside [0,63]; the audit guest has no iwn hardware, so no runtime
reproduction. The loop-termination analysis is decidable from source.

## Analysis

- `sc->rxq.stat->closed_count` is DMA-filled by the firmware;
  `iwn_notif_intr()` reads it as `hw = le16toh(...) & 0xfff`
  (if_iwn.c:3900) — range [0, 4095].
- The RX ring holds `IWN_RX_RING_COUNT = 64` buffers (if_iwnreg.h:29-30);
  `sc->rxq.cur` is maintained modulo 64 (if_iwn.c:4056).
- Termination condition `sc->rxq.cur != hw` (if_iwn.c:3901): for hw in
  [64, 4095], `cur` (always < 64) can never equal `hw` → the while-loop at
  3901-4057 never exits.
- The loop body dispatches `desc->type` handlers (iwn_rx_done etc.) with the
  lock held; none of them advance `hw`. The interrupt thread spins
  indefinitely → system wedge (DoS), not a panic.

Inside the loop, indexing is bounded (`data[sc->rxq.cur]` with cur < 64), so
this is a pure liveness defect — no OOB. Severity Low (firmware-triggered
DoS), confidence likely (arithmetic certain; whether real firmware can emit
such a value is unproven — 12-bit register semantics suggest hardware
truncation is expected to keep it within the ring, which the driver should
not rely on).

Related hardening: the same function trusts `desc->len`/`desc->type` from
the buffers each iteration — covered by DF-1123/1124 family.

## Fix

`hw &= (IWN_RX_RING_COUNT - 1)` or an explicit range check + device restart.

## 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.
