# DF-2518 — OOB array access in sili_port_read_ncq_error

## Verdict: NOT REPRODUCED (HW-gated) — source bug CONFIRMED

## Hardware gate

No SiliconImage 3124/3132 SATA HBA in guest: `kldstat` shows only kernel/ehci/xhci;
`pciconf -l` shows no SiliconImage PCI device.

## Source trace (confirmed real bug)

**File:** `sys/dev/disk/sili/sili.c:2138-2140`

```c
err_slot = log->err_regs.type & ATA_LOG_10H_TYPE_TAG_MASK;   // 5-bit, range 0..31
ccb = &ap->ap_ccbs[err_slot];                                 // OOB when err_slot == 31
```

`ap->ap_ccbs` is allocated as `kmalloc(sizeof(struct sili_ccb) * sc->sc_ncmds, ...)`
(line 211). `sc_ncmds` is typically 31. So `ap_ccbs` has indices 0..30. The NCQ tag
is a 5-bit field (0..31); `err_slot == 31` is OOB. The "bounds check" at line 2141
reads `ccb->ccb_slot` from the OOB CCB rather than validating `err_slot`. If the OOB
memory matches an expired slot bit, `memcpy` writes device-controlled FIS data through
a wild `ccb_prb` pointer read from OOB heap — wild-pointer write or NULL-deref panic.

## Fix

Added `if (err_slot >= sc->sc_ncmds) { ... break; }` validation before indexing
`ap->ap_ccbs`. See `fix.diff`.

## Impact (on HW that has the HBA)

Medium — OOB heap read/write via device-supplied NCQ error log page tag=31.
