# DF-5522 VERDICT — REPRODUCED (wire-protocol conformance bug, both block directions)

## The bug

`iicsmb_bwrite()` (`sys/bus/iicbus/iicsmb.c:463-482`) writes `[cmd]` then
`count` raw data bytes — it never transmits the SMBus byte-count that the
Block Write protocol places between the command and the data
(SMBus spec 2.0 §"Block Write": Write, Command, Byte Count, Data...).
`iicsmb_bread()` (`iicsmb.c:485-507`) symmetrically never consumes the
count byte the slave sends after the repeated start — it transfers
`*count` raw bytes and reports the raw transfer length.

Every other in-tree smbus controller driver does both: `ichsmb_bwrite`
programs `ICH_D0 = count` and the ICH hardware transmits it
(`sys/bus/smbus/ichsmb/ichsmb.c`, ichsmb_bwrite), `ichsmb_bread` returns
`sc->block_count` read off the wire; intpm/amdsmb are equivalent.  ig4's
write-side variant of this exact mistake was filed as DF-5385 (Low).

Consequences for real consumers: `/dev/smb` block ioctls through an
iicsmb-backed bus put the device's count byte into the caller's data
(stream shifted one byte, length wrong); `ipmi_ssif` (the only in-tree
kernel block-transfer consumer) mis-parses every SSIF reply
(`ssif_buf[0]` is the BMC's count byte, not the multi-part indicator it
tests) and its Block Writes are NAKed by any spec-compliant BMC —
IPMI-over-SSIF through this bridge cannot work.

## Verification

Rig (see DF-5521 pack): software controller whose slave is deliberately
SPEC-COMPLIANT (sends `[count][data...]`, continues across reads).
Stock modules — `run.baseline.log`:

  WRITE len=1 bytes: 07
  WRITE len=5 bytes: de ad be ef 99        <- no count byte between them

Fixed modules — `run.fixed.log`:

  WRITE len=1 bytes: 07
  WRITE len=1 bytes: 05                    <- count byte on the wire
  WRITE len=5 bytes: de ad be ef 99
  ...
  READ req_len=1  (consumes the device's count byte = 08)
  READ req_len=8  (reads exactly the device-declared block)
  => rcount=8, rbuf=a0 a1 a2 a3 a4 a5 a6 a7 (unshifted, deterministic)

No memory-safety impact by itself (lengths stay bounded by the callers);
correctness/data-integrity class — severity Low, consistent with DF-5385.

## Fix

`fix.diff`: transmit the count byte in bwrite; in bread read the device
count first, clamp it to the caller's `*count` and to the 32-byte SMBus
block limit, then transfer exactly that many bytes and report it.
Note: the new bwrite error path (`goto error` on count-byte write failure)
inherits DF-1095's known started-state issue until that fix lands; the
rewritten bread STOPs on all paths as before.

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
