alpm_wait() off-by-one: while(count--)/if(!count) makes SMB_ETIMEOUT unreachable on genuine SMBus timeouts (silent success with stale SMBHDATA/SMBHBLOCK data) and spuriously fails last-poll completions β DF-4737/DF-4549 family
Summary
Post-decrement loop leaves count==-1 on exhaustion so the !count timeout never fires - a genuinely timed-out transaction returns ENOERR and every caller copies stale register data as if the read succeeded; final-poll completions are spuriously failed. Line-for-line same family as viapm/amdpm. ALi M1543 hw-gated; root-only /dev/smb + in-kernel consumers. count<0 one-line fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4739 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| alpm_wait_offbyone_demo.c | β | 3.8 KB | view raw | |
| build.sh | β | 100 B | view raw | |
| run.sh | β | 92 B | view raw | |
| run.log | β | 442 B | view raw | |
| guest_hw_evidence.txt | β | 61 B | view raw | |
| env.txt | β | 166 B | view raw | |
| fix.diff | β | 281 B | view raw | |
| verdict.json | β | 2.9 KB | view raw |
Fix verification
not_testablenot_testable: kernel path requires ALi M1543 PMU hardware absent from the guest; the one-line diff is validated in-silico by the demo's fixed-loop variant (case C reports SMB_ETIMEOUT, case D succeeds β run.log).
fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
run.log (guest cc 8.3 build + both failure modes + fixed-loop validation); guest_hw_evidence.txt (pciconf: no 10b9 PMU device; kldload alpm succeeds, no attach, no /dev/smb*); VERDICT.md (line-by-line root cause at alpm.c:305/308/316)
PoC changes
No seed existed; authored replica of the alpm_wait loop with fixture register reads plus an in-demo fixed-loop variant, compiled and executed on the guest.
Verified recommended fix
Change if (!count) to if (count < 0) in alpm_wait() at alpm.c:316 (loop exhaustion leaves count == -1; completion on the final poll leaves count == 0 and must not be a timeout).
Verdict
Logic defect certain by C semantics and proven by a guest-compiled exact replica of the alpm_wait loop (run.log: perpetual-BUSY -> error=0x0, SMB_ETIMEOUT never reported; final-poll completion -> error=0x20, spurious failure). The in-kernel path is hardware-gated: no AcerLabs M15x3 PMU (10b9:7101) PCI device exists in the QEMU guest (guest_hw_evidence.txt), so alpm.ko loads but never attaches and the smbus interface is unreachable (/dev/smb* absent). Surface is root-only where it does exist (0600 root:wheel /dev/smbN) plus in-kernel smbus consumers; impact is silent stale-data success on genuine SMBus timeouts (data integrity) plus rare spurious failure of last-poll completions, not memory corruption. Line-for-line same while(count--)/if(!count) defect family as DF-4549 (viapm.c:574/587) and DF-4737 (amdpm.c:308/319); intpm.c shows the correct explicit-return pattern.
No comments yet.