# DF-3629 — iwm_rx_tx_cmd: firmware-supplied qid/idx index sc->txq[]/ring->data[] without bounds checks

## Where
`sys/dev/netif/iwm/if_iwm.c:3588-3632` (`iwm_rx_tx_cmd`), reached from
`iwm_handle_rxb()` at `sys/dev/netif/iwm/if_iwm.c:5453-5455` for every
`IWM_TX_CMD` (0x1c) notification delivered by the firmware.

## What
```c
idx = cmd_hdr->idx;          /* uint8_t: 0..255  */
qid = cmd_hdr->qid;          /* uint8_t: 0..255  */
ring = &sc->txq[qid];        /* sc->txq[IWM_MAX_QUEUES == 31]  (if_iwmvar.h:447, if_iwmreg.h:1923) */
txd = &ring->data[idx];      /* ring->data[IWM_TX_RING_COUNT == 256] */
in = txd->in;                /* wild pointer for qid >= 31 */
m  = txd->m;
```
`cmd_hdr` is the `iwm_cmd_header` of an RX packet that the device DMA'd into
host memory — a fully firmware-controlled byte pattern. There is **no**
validation of `qid` against `nitems(sc->txq)` (31) nor `idx` against
`IWM_TX_RING_COUNT` (256). `idx` happens to be safe (uint8_t < 256), but any
`qid` in 31..255 indexes past the end of `sc->txq[]` inside `struct
iwm_softc`. Consequences on the OOB ring:
- `iwm_rx_tx_cmd_single(sc, pkt, in)` dereferences `in->in_ni.ni_vap`,
  `vap->iv_bss->ni_txrate` — wild-pointer reads;
- `bus_dmamap_sync/unload(ring->data_dmat, txd->map, ...)` with garbage
  tag/map values;
- **writes**: `txd->done = 1; txd->m = NULL; txd->in = NULL;`
  (`if_iwm.c:3620-3622`) at attacker(chosen-queue)-offset memory, plus
  `sc->qfullmsk &= ~(1 << qid)` (undefined shift for qid ≥ 32) and
  `--ring->queued` on OOB memory;
- `ieee80211_tx_complete(&in->in_ni, m, status)` on a wild node pointer —
  UAF-style secondary corruption.

This is the iwm twin of the iwn finding DF-1122
(`iwn_rx_compressed_ba` unbounded qid), same CWE-129/CWE-787 class.

## Threat model
Requires malicious, buggy, or compromised firmware (or a Thunderbolt/PCIe
device spoofing the iwm PCI ID). Intel ucode has shipped length/index
inconsistencies before (the DF-1145 class). The device DMA content is
untrusted from the driver's perspective; the driver must validate indices
before array use. This bug is *write*-capable, unlike the DF-1145 read.

## Reproduce (kernel path)
Not possible on the audit guest: no Intel Wireless PCI device is present
(`pciconf -l` shows none; `kldload if_iwm` attaches nothing). Source-level
certainty: see VERDICT.md. The index arithmetic is:

    qid = 255  ->  &sc->txq[255]  =  sc + offsetof(iwm_softc, txq)
                                      + 255 * sizeof(struct iwm_tx_ring)
                 (224 * sizeof(iwm_tx_ring) bytes past the array end;
                  sizeof(iwm_tx_ring) ≈ 0x4000+ incl. 256 iwm_tx_data)

## Fix
`fix.diff` in this directory (bounds-check qid/idx, drop the completion).
