# DF-1287 — siba_pci_sprom dispatches rev-4/5/8 parsers without buffer-size check

## Finding
`siba_pci_sprom` (`sys/dev/netif/bwn/siba/siba_core.c:1372`) initially
allocates a 64-word SPROM buffer (`SIBA_SPROMSIZE_R123 = 64`,
`sibareg.h:303`) at line 1378, reads it via `siba_sprom_read` at line 1382
(which also sets `siba->siba_spromsize = 64`), and runs a CRC check at line
1383.

Only if the CRC **fails** does it free and realloc a 220-word
(`SIBA_SPROMSIZE_R4 = 220`, `sibareg.h:304`) buffer at lines 1385-1390.

Then at line 1398 it extracts the SPROM revision byte from the **last word**
of whatever buffer it ended up with, and dispatches to a per-revision
parser (lines 1403-1428):
- rev 1/2/3 → `siba_sprom_r123` (stays within 64 words)
- rev 4/5   → `siba_sprom_r45`
- rev 8     → `siba_sprom_r8`

`siba_sprom_r45` indexes `SIBA_SPROM4_PWR_INFO_CORE0 = 0x1080`
(`sibareg.h:402`) through `SIBA_SPROM4_PWR_INFO_CORE3 = 0x110A`
(`sibareg.h:405`). With `SIBA_OFFSET(o) = (o - SIBA_SPROM_BASE) / 2` and
`SIBA_SPROM_BASE = 0x1000` (`sibareg.h:305`), this is word index 64..133 plus
the per-core `pa` offsets, well beyond the 64-word R123 buffer. Similarly
`siba_sprom_r8` indexes up to word ~158 (`SIBA_SPROM8_CDDPO = 0x1192`,
`SIBA_SPROM8_PWR_INFO_CORE3 = 0x1120`, etc.).

The trigger is straightforward: a crafted SPROM image whose 64-word R123
CRC-8 is **valid** (so the realloc path is skipped), and whose last byte
encodes rev 4, 5, or 8. The next `siba_sprom_r45` / `r8` call then reads
up to ~276 bytes past the 128-byte allocation.

## Fix
Validate `siba->siba_spromsize >= SIBA_SPROMSIZE_R4` before dispatching to
`siba_sprom_r45` or `siba_sprom_r8` in any of the three dispatch sites
(chipid 0x4321 path, rev 4/5 case, rev 8 case). If the buffer is too small,
log a warning and fall back to the R123 parser (which is the only one
guaranteed to fit).

## Verification on this guest
- The siba_bwn / bwn drivers are statically compiled in
  (`device siba_bwn` and `device bwn` in
  `sys/config/X86_64_GENERIC:267-268`) and present in `kldstat -v`
  (`siba_bwn/bwn`).
- The QEMU guest has **no Broadcom BCM43xx PCI NIC** (`pciconf -l` shows
  only i440FX/PIIX/ACPI/virtio-net/virtio-blk/std-VGA), so `siba_pci_probe`
  never matches and `siba_pci_sprom` is never called. Bug is **not
  runtime-triggerable on this guest**.
- Source-level confirmation:
  - `siba_core.c:1378` — initial alloc is `SIBA_SPROMSIZE_R123 * 2 = 128` bytes.
  - `siba_core.c:1382-1383` — `siba_sprom_read` then CRC; realloc only on
    CRC fail.
  - `siba_core.c:1398` — `sprom->rev = buf[siba_spromsize - 1] & 0xff`.
  - `siba_core.c:1408, 1418, 1421` — dispatch to `r45` / `r8` with no buffer
    size check.
  - `siba_core.c:1632-1710` — `siba_sprom_r45` accesses offsets
    `SIBA_OFFSET(0x1080..0x110A + extra)` = words 64..133+, far past 64.
  - `siba_core.c:1727-1860` — `siba_sprom_r8` accesses up to word ~158.
  - `sibareg.h:303-305, 402-405` — confirming the constants.
- Fix verified to compile (combined build with DF-1278/1279/1280/1285).

## Realistic impact ceiling
Hardware-attacker (PCIe WiFi card or USB-attached Broadcom chip with crafted
SPROM) heap OOB read past a 128-byte `M_DEVBUF` allocation at attach time.
The read feeds `struct siba_sprom` fields — information leak of adjacent
slab data is the realistic ceiling; no write primitive through this path.
