# DF-5506 VERDICT — REPRODUCED (in-kernel, production source, emulated AMD-8111 EC); fix validated in the same rig

## Bottom line

All three timeout detectors in the amdsmb poll state machine are dead
code — the `while (x-- && cond)` / `if (x == 0)` post-decrement idiom
leaves the counter at -1 when the budget is exhausted, so exhaustion is
never detected:

- `amdsmb_ec_wait_write` (sys/bus/smbus/amdsmb/amdsmb.c:214-219): 500-poll
  IBF budget → returns 0 ("go ahead") on exhaustion.
- `amdsmb_ec_wait_read` (amdsmb.c:228-234): 500-poll OBF budget → returns
  0 on exhaustion; caller then reads a stale EC_DATA byte as register
  data.
- `amdsmb_wait` (amdsmb.c:287-293): 10000 × DELAY(500) PRTCL budget →
  `SMB_ETIMEOUT` at amdsmb.c:293 is unreachable; the driver proceeds to
  read SMB_STS of a still-busy/wedged controller and maps whatever it
  finds (0x00 → `SMB_ENOERR`) onto the *current* transaction.

Consequences, all demonstrated by executing the unmodified production
source in-kernel against a datasheet-faithful AMD-8111 EC register
emulator (T1/T2/T2b in run.log):

1. A wedged SMBus transaction is reported as SUCCESS after a 5.44 s
   busy-spin under the exclusive `sc->lock`, returning the PREVIOUS
   transaction's data and byte count as the new transaction's result
   (cross-transaction data confusion; every smbus op is affected, not
   just block reads).
2. A wedged EC input path (IBF stuck) never stops the driver: it keeps
   writing CMD/address/data bytes into a controller that is not
   consuming them.
3. A wedged EC output path (OBF never sets) yields stale EC data bytes
   accepted as arbitrary SMB register values (e.g. SMB_BCNT — feeding
   the known DF-1091 count path with a *stale* rather than
   slave-controlled value).

Because the same dead branches are the ONLY failure returns of
`amdsmb_ec_read`/`amdsmb_ec_write`, the drivers' ignored-return-codes
issue (every call site in amdsmb.c:350-530) is moot until this is fixed —
the error plumbing is unreachable end-to-end.

Impact ceiling: local DoS (a `/dev/smbN` opener — root on stock installs;
operator-group on some — can serialize 5.4 s lock-held busy-spins per
ioctl against stuck hardware) plus silent data corruption for legitimate
SMBus clients (sensors, EDID, battery). No memory-safety impact: the
stale values feed bounded paths (the unbounded one is known DF-1091).
Severity Low, matching the ichsmb sibling (DF-5461, timeout/abort family)
and ig4 DF-5386 (silent success family).

## Reproduction honesty

The AMD-8111 SMBus 2.0 controller (PCI 1022:746a) has no QEMU machine
model — no stock or buildable rig executes this driver on emulated
hardware. The evidence class is the production-code KLD harness used by
the ichsmb/ig4 batches, taken one step further: the harness #includes the
real amdsmb.c (byte-identity asserted at build time, build.log:1) and
interposes a stateful register-level emulation of the EC interface the
driver actually drives (EC_CMD_RD/WR handshake with IBF/OBF flags). The
executed code is the production text verbatim; only the ultimate port
I/O is emulated. The observed behavior (10002 polls / 5440 ms / rc=0) is
deterministic C semantics, not emulator timing: the dead-branch proof is
static (the counter provably exits at -1), the run makes it visible.

## Fix validation (same rig, fix.diff applied to the harness copy)

- Baseline run.log T1: rc=0 (fake success), stale data+count, 5440 ms.
  Fixed run_fixed.log T1: **rc=32 (SMB_ETIMEOUT)**, zero bytes copied.
- Baseline T2/T2b: rc=0 with 502/503 polls ("success" past exhaustion).
  Fixed: **rc=1**, and the previously-dead device_printf timeout messages
  now execute (they print "unknown:" because the harness fake device_t
  is minimal — cosmetic, noted).
- Healthy-path regression: T0 PASS in both builds.
- Residual (documented, not claimed fixed): the fixed driver still
  busy-waits the full 5.4 s before reporting — the EC register interface
  exposes no transaction-abort (KILL) mechanism; converting the spin to
  a sleep/timeout scheme is an upstream design decision.

## Kernel references

sys/bus/smbus/amdsmb/amdsmb.c:212-221 (wait_write), :224-235
(wait_read), :277-294 (wait; dead SMB_ETIMEOUT at :293), :296-324 (STS
read of wedged controller mapped to SMB_ENOERR), :349-356 et al.
(lock-held across the entire spin), sys/dev/smbus/smb/smb.c:206-359
(reachability: /dev/smb ioctls, root-gated device).

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