# DF-2517 — Heap OOB write in sili_load_prb_callback via unchecked DMA segment count

## 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. The sili driver does not attach.

## Source trace (confirmed real bug)

**File:** `sys/dev/disk/sili/sili.c:1245` (callback at 1238-1268)

```c
KKASSERT(nsegs <= SILI_MAX_SGET);   // line 1245: WRONG bound
```

`SILI_MAX_SGET = 128 - 4 = 124` (`sili.h:640`). The PRB SGE table is filled in
blocks of 4 entries (3 data + 1 link). So the maximum number of **data** segments
is `SILI_MAX_SGET * 3 / 4 = 93`, not 124. The DMA tag allows 124 segments. When
`nsegs >= 94`, the while-loop (1249-1265) writes `prb_sge[0..167]` — a 44-entry
OOB write past the 124-element `prb_sge` array into the adjacent PRB slot. The
`KKASSERT` at 1245 checks the wrong bound and does not catch this.

## Fix

Changed `KKASSERT(nsegs <= SILI_MAX_SGET)` to
`KKASSERT(nsegs <= (SILI_MAX_SGET * 3 / 4))`. See `fix.diff`.

## Impact (on HW that has the HBA)

High — heap OOB write via large non-contiguous DMA buffer. WRITE corrupts kernel
memory with disk data; READ leaks kernel heap to disk. Reachable via ATA PASS-16.
