# DF-3633 — iwm_notif_intr: 12-bit closed_rb_num vs 256/512-entry ring → non-terminating interrupt-loop hang

## Where
`sys/dev/netif/iwm/if_iwm.c:5693-5737` (`iwm_notif_intr`), constants
`if_iwmvar.h:287-288` (`IWM_RX_LEGACY_RING_COUNT 256`,
`IWM_RX_MQ_RING_COUNT 512`), `struct iwm_rb_status.closed_rb_num`
documentation "closed_rb_num [0:11]" (`if_iwmreg.h`, iwl-fh.h block).

## What
```c
hw = le16toh(sc->rxq.stat->closed_rb_num) & 0xfff;   /* if_iwm.c:5710 */

while (sc->rxq.cur != hw) {                          /* :5715 */
        data = &ring->data[ring->cur];
        ...
        iwm_handle_rxb(sc, data->m);
        ring->cur = (ring->cur + 1) % count;         /* count = 256 / 512 */
}
```
`sc->rxq.stat` is device-DMA'd shared memory. `ring->cur` cycles through
`[0, count)`, but `hw` is masked to 12 bits (0..4095). Any device-written
`closed_rb_num` in `[count, 4096)` (256..4095 legacy, 512..4095 mq) can
never equal `ring->cur` → the loop never terminates: the interrupt handler
spins forever reprocessing the ring, holding `sc->sc_lk`, with interrupts
masked — a hard system hang (no watchdog, no panic, no serial console
progress). This is the iwm twin of iwn's DF-3581 ("12-bit firmware
closed_count vs 64-slot ring"), where the ring-size mismatch class was
established.

Even when the loop does terminate, `hw` values ≥ count are never validated,
so `(ring->cur + 1) % count` vs raw `hw` bookkeeping stays inconsistent
(`hw = (hw == 0) ? count - 1 : hw - 1;` at `:5735` then feeds a bogus write
pointer to the device).

## Threat model
Requires an errant/malicious device or firmware writing an out-of-range
`closed_rb_num` (device DMA is untrusted input per this audit's policy;
also plausible on firmware hiccup). Impact: unattended hard hang (DoS) of
the whole system — no panic, no dump.

## Reproduce
Kernel path needs iwm hardware (absent on guest — env.txt). Logic: pick
hw=300, count=256: cur cycles 0..255 forever.

## Fix
`fix.diff` — mask `hw` with `(count - 1)`, matching the ring the driver
actually walks (values ≥ count are impossible on compliant hardware, so the
mask only changes behavior for the malicious/errant case).
