# DF-2026 — Multi-part SSIF response read loop has no iteration cap

## Verdict
**CONFIRMED (source-trace); NOT REPRODUCED AT RUNTIME — HW-GATED.**
Status: `inconclusive`, reproduced=0. The unbounded loop is real; it is unreachable on
this guest (no BMC, no `ichsmb`/`amdsmb`, `ipmi.ko` not loaded).

## Mechanism (confirmed)

The multi-part **response read** loop is an unconditional `for (;;)`:
- `ipmi_ssif.c:257` — `for (;;) {`
- `ipmi_ssif.c:260-262` — each iteration calls `smbus_bread(..., SMBUS_READ_CONT, &count,
  ssif_buf);` so the BMC controls `ssif_buf[0]` (block marker) on every iteration.
- `ipmi_ssif.c:274` — `if (ssif_buf[0] != 0xff && ssif_buf[0] != block) goto fail;`  a
  block that is neither `0xff` nor the expected incrementing `block` number is rejected.
- `ipmi_ssif.c:297-299` — `if (ssif_buf[0] != 0xff) break; block++;`

There is **no maximum iteration counter**. A BMC that returns `0xff` (or a sequence of
incrementing/matching block numbers) on every READ_CONT keeps the loop spinning: `block`
increments and wraps as a `u_char` (255 → 0 → …), and the `0xff` marker short-circuits the
line-274 guard, so the loop never exits. The only other exits are an `smbus_bread` error
(`goto fail`) — which the BMC can simply not produce. Result: **infinite kernel-loop DoS**
(wedge) at IPL of the SSIF thread, driven entirely by attacker-controlled BMC responses.
Class: CWE-835 (reachable assertion / unbounded iteration).

(Observation, out of scope for this fix: the line-297 exit condition
`if (ssif_buf[0] != 0xff) break;` reads as if a *non-0xff* block terminates the transfer,
which is the inverse of the line-273 comment "0xff marks the last block"; regardless of the
exact intended termination semantics, the absence of an iteration cap is the confirmed
defect and the cap below closes the DoS.)

## Why it is not reproduced on this guest (HW-gate)
Identical to DF-2024/2025: the loop body is only entered through `ssif_polled_request()`,
which is only reachable with a real BMC on an SMBus block controller. No BMC on this guest
⇒ dead code at runtime. Threat actor = malicious/compromised BMC. No escalation chain
(this is a DoS/infinite-loop class, not memory corruption; even on real hardware it is a
wedge, not a write primitive).

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

## Fix (`fix.diff`)
In `sys/dev/misc/ipmi/ipmi_ssif.c`: add `#define SSIF_MAX_READ_BLOCKS 256`, declare
`int readblocks`, initialize it before the loop, and bail (`goto fail`) once the iteration
count exceeds the cap. 256 blocks × 31 payload bytes ≈ 8 KB, far above any legitimate IPMI
response while bounding the loop deterministically. The fix does not alter the existing
block-termination logic, so it is safe regardless of the `0xff`/block-number semantics.
Matches the finding proposal's intent (add an iteration cap).

## 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`.
