# DF-2025 — Missing upper-bound on BMC-supplied response byte count

## Verdict
**CONFIRMED (source-trace); NOT REPRODUCED AT RUNTIME — HW-GATED.**
Status: `inconclusive`, reproduced=0. The bug is real (confirmed by tracing the SSIF
layer and both in-tree SMBus block-read backends), but unreachable on this guest: no BMC,
no `ichsmb`/`amdsmb` block-transfer controller, `ipmi.ko` not loaded.

## Mechanism (confirmed)

`ssif_polled_request()` reads IPMI responses into a **fixed 32-byte stack buffer**:
- `ipmi_ssif.c:73` — `u_char ssif_buf[SMBUS_DATA_SIZE];`  (SMBUS_DATA_SIZE = 32)
- `ipmi_ssif.c:76` — `u_char ... count ...`  (count is `u_char`, range 0..255)
- `ipmi_ssif.c:183` — `count = SMBUS_DATA_SIZE;` then
  `smbus_bread(smbus, ..., &count, ssif_buf);`

The `count` returned by `smbus_bread` is the **BMC-supplied byte count** and is **never
validated against `SMBUS_DATA_SIZE`**. The in-tree backends confirm this:
- `sys/bus/smbus/ichsmb/ichsmb.c:440-441` — `bcopy(sc->block_data, buf, min(sc->block_count,
  *count)); *count = sc->block_count;`  → the buffer copy is capped at `min(count,32)` so
  `ssif_buf` itself is **not** overflowed, BUT `*count` is set to `sc->block_count`, which
  the ISR takes straight from hardware: `ichsmb.c:575  sc->block_count = bus_read_1(io_res,
  ICH_D0);` (a raw 0..255 byte).
- `sys/bus/smbus/amdsmb/amdsmb.c:533-539` — `amdsmb_ec_read(sc, SMB_BCNT, &len); ...;
  *count = len;`  → likewise returns the raw BMC byte count (0..255), unclamped.

So after `smbus_bread` returns, `count` may be up to 255 while only ≤32 bytes of `ssif_buf`
were populated. The SSIF code then indexes `ssif_buf` using `count`:
- Single-read path `ipmi_ssif.c:240-242` — `len = count - 3; bcopy(&ssif_buf[3],
  req->ir_reply, min(req->ir_replybuflen, len));`  With e.g. `count == 200`, `len = 197`,
  so `bcopy` reads up to `min(replybuflen,197)` bytes from `&ssif_buf[3]` — but `ssif_buf`
  is only 32 bytes (indices 0..31). Bytes `ssif_buf[32..]` are **kernel stack** past the
  buffer, leaked into `req->ir_reply` ⇒ returned to userspace. **Kernel stack OOB read /
  info leak.** (Same class applies to the multi-part `bcopy` at lines 291-293.)
- A trivially-malicious BMC need only report `count > 32`.

Note: this is distinct from DF-2024 (write-path underflow). DF-2025 is the **read-response
path** and the defect is a missing upper bound on the trusted `count`.

## Why it is not reproduced on this guest (HW-gate)
Same as DF-2024: no BMC / no ichsmb-or-amdsmb block controller / `ipmi.ko` not loaded, so
`smbus_bread` is never driven with attacker data from userspace. The threat actor is a
malicious or compromised BMC. No escalation chain developed (trigger not reachable from the
unprivileged syscall surface on this guest).

## PoC changes
None (source-only verification).

## Fix (`fix.diff`)
In `sys/dev/misc/ipmi/ipmi_ssif.c`, reject `count > SMBUS_DATA_SIZE` immediately after each
`smbus_bread` (both the READ_START call and the READ_CONT call inside the multi-part loop),
treating an oversized count as a malformed response (`goto fail`), consistent with the
existing `if (count < 3)` short-reply check at line 215. This prevents any subsequent
indexing of `ssif_buf` past its 32-byte bounds. Matches the finding proposal's intent.

## Fix validation (Phase 8)
Combined kernel build with all four fixes: **rc=0, 0 warnings, 0 errors under -Werror**;
`ipmi_ssif.c` recompiled, `ipmi.ko` relinked (see `fix_build.log`). HW-gated ⇒
`fix_status = not_testable` (applies + compiles + traced to close the path; no runtime
demonstration possible without a BMC).
