# DF-1286 — SPROM rev4/5/8 TXPID parser reads kernel heap at negative indices (unported offset constants)

**File:** `sys/dev/netif/bwn/siba/sibareg.h:363-386` (buggy constants);
sink: `sys/dev/netif/bwn/siba/siba_core.c:1513` / `:1591-1628`
**Class:** CWE-125 Out-of-bounds Read (kernel heap info leak)
**Severity:** High

## The bug (source-confirmed)

`siba_sprom_r458()` (`siba_core.c:1591`) parses the Broadcom SPROM TX-power-id
fields for SPROM revisions 4/5/8 (the dominant format on BCM4321/4322/4325/4328).
Each field is read via the macro (`siba_core.c:1513`):

```c
#define SIBA_OFFSET(offset)  (((offset) - SIBA_SPROM_BASE) / sizeof(uint16_t))  /* :1509 */
#define SIBA_SHIFTOUT(_var, _offset, _mask) \
        out->_var = SIBA_SHIFTOUT_SUB(in[SIBA_OFFSET(_offset)], (_mask))        /* :1513 */
```

`SIBA_SPROM_BASE = 0x1000` (`sibareg.h:305`). For `SIBA_OFFSET` to yield a valid
non-negative word index, the constant must be an **absolute** byte address in the
`0x10xx` range. Every sibling `SIBA_SPROM4_*` offset constant is absolute — e.g.
`MAC_80211BG=0x104c`, `BFHIGH=0x1046`, `AGAIN23=0x1060`, `MAXP_BG=0x1080`.

**But** the TXPID block (`sibareg.h:363-386`) was left as **Linux-style relative**
word offsets:

| constant | value | `SIBA_OFFSET` |
|---|---|---|
| `SIBA_SPROM4_TXPID2G01` | `0x0062` | **-1999** |
| `SIBA_SPROM4_TXPID2G23` | `0x0064` | **-1998** |
| `SIBA_SPROM4_TXPID5G01` | `0x0066` | **-1997** |
| ... | ... | ... |
| `SIBA_SPROM4_TXPID5GH23` | `0x0070` | **-1992** |

`siba_sprom_r458` therefore performs `in[-1999 .. -1992]` — 16 reads (8 offsets,
each used for two TXPID values) of kernel heap **3984–3998 bytes before** the SPROM
buffer allocation. The leaked words surface to userland as the
`SIBA_SPROMVAR_TXPID_*` sysctl spromvars (a kernel-heap / KASLR-bypass info leak).

## Reachability / threat model

The bwn/siba driver attaches to Broadcom BCM43xx (PCI/CardBus) WiFi. **No such
device is present** in the audit QEMU guest, so `siba_sprom_r458` is not
runtime-reachable here. On hardware, the parse runs at attach time (boot or
device insertion), and the result is world-readable via sysctl. This is a
straight porting bug — the fix is purely a constant correction. See `VERDICT.md`.

## Reproduce (harness)

```sh
./build.sh && ./run.sh
```

Decisive output:
```
constant 0x0062 -> SIBA_OFFSET = -1999 => NEGATIVE: in[-1999] reads -3998 bytes BEFORE the SPROM buffer (heap leak)
...
FIXED constants 0x1062..0x1070: SIBA_OFFSET(0x1062) = 49 -> in[49] reads the REAL SPROM word
```

## Fix

`fix.diff` corrects the 8 TXPID offset constants to absolute values
(`0x0062`→`0x1062` … `0x0070`→`0x1070`), matching every sibling SPROM4 constant
and the SPROM1 `PA0B2=0x1062` already in this file. Validated: applies cleanly;
the `siba_bwn` module compiles with `-Werror` in-tree.
