# DF-1240 — iwi_checkforqos unbounded notif->len (OOB read up to ~292B)

## Verdict: NOT REPRODUCED (dead code at runtime — no hardware)

## Mechanism (source-level, confirmed real)

`iwi_notification_intr()` at `sys/dev/netif/iwi/if_iwi.c:1455` handles
firmware notifications. For the ASSOCIATION notification, it calls:

```c
// line 1545-1556
assoc = (struct iwi_notif_association *)(notif + 1);
switch (assoc->state) {
case IWI_ASSOC_SUCCESS:
    ...
    iwi_checkforqos(vap,
        (const struct ieee80211_frame *)(assoc+1),
        le16toh(notif->len) - sizeof(*assoc) - 1);  // <-- len from firmware
```

`notif->len` is a firmware-supplied `uint16_t` (0–65535). The subtraction
`le16toh(notif->len) - sizeof(*assoc) - 1` can also underflow to a huge
`int` value if `notif->len < 13`.

Inside `iwi_checkforqos` (line 1368), the guard at 1378 is too loose:
```c
if (!(sizeof(*wh)+8 < len && len < IEEE80211_MAX_LEN) || ...)  // IEEE80211_MAX_LEN=2313
    return;
frm = (const uint8_t *)&wh[1];
efrm = ((const uint8_t *) wh) + len;   // <-- can point past cluster
```

The frame `wh = (assoc+1)` sits at cluster offset 28 (iwi_hdr=4 +
iwi_notif=12 + assoc=12). The cluster is `MCLBYTES` (2048). So safe
`len` max = 2048 − 28 = **2020**. But the guard allows up to 2312, which
is **292 bytes past the cluster**. The IE walk at lines 1401–1410
dereferences `frm[]` and `efrm` which are now OOB in the mbuf cluster /
adjacent kernel heap.

**Struct sizes confirmed:** `iwi_hdr`=4B, `iwi_notif`=12B (reserved[2]=8
+ type=1 + flags=1 + len=2), `iwi_notif_association`=12B (state=1 +
pad[11]=11). Prefix before frame = 4+12+12 = 28B.

**The bug is real in source.** A malicious AP / compromised firmware can
drive `efrm` up to ~292 bytes past the DMA cluster, causing an OOB read
in `iwi_checkforqos`.

## Why it cannot reproduce on this guest

Same as DF-1239: `iwi` (Intel PRO/Wireless 2200BG/2915ABG) is **not in
GENERIC, not loaded, no WiFi hardware** on the QEMU guest. The
notification interrupt path is unreachable.

**Valid hard blocker: dead/unreachable at runtime.** Threat model is a
malicious WiFi AP or compromised firmware on a real system with the card.

## Fix

`fix.diff` guards the subtraction against underflow and clamps the
result to the actual cluster space (`MCLBYTES - sizeof(iwi_hdr) -
sizeof(iwi_notif) - sizeof(*assoc)` = 2020). Compiled successfully as
`if_iwi.ko`.

## Impact

- **On this guest**: none (dead code, no WiFi hardware).
- **On a real system**: OOB read of up to ~292 bytes of kernel heap per
  association-response notification, from a remote (radio-range) attacker
  via a malicious AP. Could leak kernel pointers (defeating KASLR on
  systems that have it) or adjacent slab data. Low real-world prevalence
  due to the old (2004-era) hardware.
