# DF-3632 — NVM sections parsed with fixed offsets against firmware-returned lengths (heap OOB reads)

## Where
`sys/dev/netif/iwm/if_iwm.c:2215-2276` (`iwm_parse_nvm_data` and its helpers
`iwm_get_sku`/`iwm_get_nvm_version`/`iwm_get_radio_cfg`/`iwm_get_n_hw_addrs`
`:2120-2161`, `iwm_set_hw_address` `:2184-2213`,
`iwm_set_hw_address_family_8000` `:2061-2118`), fed by `iwm_nvm_init()`
`:2339-2393`.

## What
Each NVM section is read from the firmware into an **exact-size** heap
allocation:

```c
temp = kmalloc(len, M_DEVBUF, M_WAITOK);   /* len == bytes the FW returned */
memcpy(temp, nvm_buffer, len);
nvm_sections[section].data = temp;         /* if_iwm.c:2367-2375 */
```

`iwm_parse_nvm_sections()` only checks that section pointers are non-NULL
(`:2290-2333`) — **the section lengths are never validated** — and then
`iwm_parse_nvm_data()` reads *fixed* word offsets from them:

- `iwm_get_sku()`: `nvm_sw[IWM_SKU=2]`, `phy_sku[IWM_SKU_8000=2]` (`:2125-2127`)
- `iwm_get_n_hw_addrs()`: `nvm_sw[3]` (`:2156-2158`)
- family 7000 channel flags:
  `memcpy(..., &nvm_sw[IWM_NVM_CHANNELS], IWM_NUM_CHANNELS*2)` where
  `IWM_NVM_CHANNELS = 0x1E0-0x1C0 = 32` (u16 index) → reads SW bytes
  `[64, 142)` (`:2266-2269`)
- family 8000 channel flags:
  `memcpy(..., &regulatory[IWM_NVM_CHANNELS_8000=0], 51*2)` → REGULATORY
  bytes `[0, 102)` (`:2270-2273`)
- LAR config: `regulatory[IWM_NVM_LAR_OFFSET_8000=0x507]` → REGULATORY
  bytes `[0xA0E, 0xA10)` = offset 2574 (`:2251-2255`) — the section must be
  ≥ 2576 bytes, never checked
- MAC override: `mac_override[1..4]` (`:2072-2073`), HW addr:
  `nvm_hw[IWM_HW_ADDR=0x15]` → HW bytes `[0x2A, 0x30)` (`:2194`)

A firmware that returns a short section (e.g. an 8-byte SW section) makes
each of these a heap OOB read past a small `kmalloc` allocation. The read
values populate `sc->nvm_data` (channel map, radio cfg, MAC address) and the
MAC is printed to the console (`if_iwm.c:6386-6389`).

## Threat model
Firmware-controlled NVM content (same trust boundary as DF-1145/DF-1898;
DF-1898 rated Low, DF-2056 rated Medium for the paging variant). No guest
iwm hardware — source-level certainty (env.txt).

## Fix
`fix.diff` — validate minimum section lengths in `iwm_parse_nvm_sections()`
before parsing (family-aware requirements, incl. the 0x507/0x4C7 LAR
offsets).
