β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-4739

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4739 Β· 8 files
FileTypeDescriptionSize
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_testable
baseline no→ patch + rebuild →patched clean

not_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
↓ fix.diffper-fix-DF-4739

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.