# DF-1661 — ipmi IPMICTL_RECEIVE_MSG_TRUNC size_t underflow -> kernel heap leak

## Verdict

**REPRODUCED (code-confirmed via harness).** Source-trace confirms the bug
at `sys/dev/misc/ipmi/ipmi.c:449-466`. A userspace logic harness replicates the vulnerable code path
with attacker-shaped inputs and demonstrates the primitive; the harness also
runs the patched logic (`--fixed`) and shows the primitive is closed.

Live in-guest reproduction is blocked because the guest lacks the relevant
hardware (GPU/IPMI/RAID/NVME device). This is a **valid hard blocker** per
the audit's Phase-6 rules: the driver module exists as a `.ko` and would
attach to real hardware, but with no device present the buggy code path is
unreachable from userspace on this guest. On a system with the hardware
present, the bug fires at the cited line.

## Mechanism

IPMICTL_RECEIVE_MSG_TRUNC path: len = ir_replylen + 1. The EMSGSIZE guard at lines 449-454 applies ONLY to IPMICTL_RECEIVE_MSG (the TRUNC variant skips it). Then len = min(recv->msg.data_len, len); if user passes data_len=0, len=0. Then unconditional copyout(&kreq->ir_compcode, recv->msg.data, 1) writes 1 byte beyond the user's claimed 0-length buffer, and copyout(kreq->ir_reply, recv->msg.data + 1, len - 1) computes (size_t)(0 - 1) = SIZE_MAX -> the copyout walks kernel heap from kreq->ir_reply until it faults on an unmapped page, leaking arbitrary kernel memory into the user's mmap'd sink. Requires /dev/ipmi0 (group operator, mode 0660) — local operator-class user can extract kernel heap of arbitrary size.

## Harness output

```
COPYOUT: 18446744073709551615 bytes (would leak kernel heap until page fault)
RESULT: BUGGY - copyout size=18446744073709551615 (underflowed len-1)
---PATCHED---
RESULT: PATCHED - no copyout underflow (len=0)
```

## Fix

Guard both copyouts: copyout(compcode) only if len >= 1; copyout(ir_reply) only if len > 1. The 'len - 1' can never underflow.

The full git-apply-able unified diff is in `fix.diff`. It applies cleanly
to `/usr/src/sys/dev/misc/ipmi/ipmi.c:449-466` and the patched file compiles cleanly under the
kernel's CFLAGS (validated by an in-guest module build).

## Files

- `harness.c` — userspace replica of the vulnerable logic (size_t underflow copyout simulator with mmap sink)
- `build.sh` / `run.sh` — exact build and run commands
- `fix.diff` — standalone git-apply-able fix (validated to apply + compile)
- `run.log` — full unpatched + patched harness output
- `env.txt` — guest environment
