amdsmb_bread uses unbounded hardware byte-count for register indexing and out-param
Summary
amdsmb_bread reads block byte-count directly from controller SMB_BCNT register into len with no validation. Non-compliant/malicious SMBus slave can return up to 255 causing loop to issue bus_read_1() at offsets SMB_DATA+i (0x04..0x102) far beyond 32-entry data register file (0x04..0x23). *count=len reports hardware length back to caller breaking contract. Buf write guarded by i<*count so buf not overwritten OOB but *count reports unbounded len so caller trusting *count reads uninitialized buffer. /dev/smbN 0600 root:wheel. Impact: out-of-range I/O register reads + inconsistent out-param. [VERIFIED pass2: reproduced - BCNT 255 slave fetches 221 registers past the 32-entry file via EC protocol offset wrap and reports count 255 against a 32-byte buffer; double HW-gated AMD-8111 plus malicious slave root-only; 32-clamp fix-validated]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2330 Β· 10 files| File | Type | Description | Size | |
|---|---|---|---|---|
| amdsmb_rig.c | β | 7.2 KB | view raw | |
| build.log | β | 207 B | view raw | |
| build.sh | β | 91 B | view raw | |
| env.txt | β | 412 B | view raw | |
| fix.diff | β | 349 B | view raw | |
| run.log | β | 2.0 KB | view raw | |
| run.sh | β | 112 B | view raw | |
| run_fixed.log | β | 1.6 KB | view raw | |
| verdict.json | β | 1.9 KB | view raw | |
| fix.diff | β | 349 B | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Evidence (decisive lines)
run.log (attack: PROOF + CONTRACT BREAK lines; edge bcnt=33; control), run_fixed.log (count_out=32, OOB=1 legitimate BCNT fetch), fix.diff
PoC changes
first model returned 224 (rig had overwritten the BCNT register in its own data fill); fixed the model to serve distinct values beyond the file
Verified recommended fix
clamp the hardware byte count to the 32-entry data register file in amdsmb_bread
Verdict
amdsmb_bread (amdsmb.c:517-547) verbatim rig with an emulated AMD-8111 SMBus controller: a non-compliant slave reporting BCNT=255 makes the loop fetch logical SMB registers 0x04..0xff via the EC protocol - 221 fetches beyond the 32-entry data register file (SMB_DATA..0x23), sweeping protocol registers after the u_char offset wraps - and sets *count=255 against a 32-byte caller buffer (contract break: caller reads 223 uninitialized bytes). With the 32 clamp the attack run is indistinguishable from the compliant control (count_out=32, only the legitimate BCNT fetch touches >0x23). Hardware-gated twice over: AMD-8111 SMBus2 controller plus a malicious slave, via root-only /dev/smbN.
No comments yet.