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

phm_wait_on_indirect_register passes (mask, value) to a (index, value, mask) callee β€” swapped arguments, currently latent

Summary

The call transposes value/mask vs the callee's parameter order (provable against the sibling at :185 which passes correctly): a caller waiting for a bit to clear would return success immediately. Currently harmless (sole caller passes value==mask); latent handshake-skip hazard for future callers. Swap one-liner fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4667 Β· 2 files
FileTypeDescriptionSize
README.md file 1.8 KB ↓ raw
verdict.json file 1007 B view raw
README.md file
↓ download raw

DF-4667 β€” phm_wait_on_indirect_register: value/mask arguments swapped (latent, Info)

File: sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c:136-149

phm_wait_on_register(struct pp_hwmgr *hwmgr, uint32_t index, uint32_t value, uint32_t mask) β€” documented "(index, value, mask)".

phm_wait_on_indirect_register (smu_helper.c:148) calls:

return phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);

i.e. mask is passed as value and value as mask β€” provable by comparing with the sibling phm_wait_for_indirect_register_unequal (smu_helper.c:185-186), which passes (value, mask) correctly for the same callee shape. With the swap, the wait condition becomes (cur & value) == (mask & value) instead of (cur & mask) == (value & mask): when value & mask == 0 the wait returns success immediately regardless of the register state; otherwise it can spuriously time out.

Current impact: none. The sole caller, smu7_check_fw_load_finish (smumgr/smu7_smumgr.c:449-452), passes value = fw_type, mask = fw_type β€” identical values, so the swap is currently harmless. Any future caller with value & mask == 0 (e.g. waiting for a bit to CLEAR: value=0) would silently skip the firmware-ready handshake and race the SMC during clock/voltage programming.

Not PoC-verified (Info severity; the defect is directly readable in the source and current callers are provably insensitive to it).

Suggested fix

--- a/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c
+++ b/sys/dev/drm/amd/powerplay/hwmgr/smu_helper.c
@@ -145,7 +145,7 @@ int phm_wait_on_indirect_register(struct pp
    cgs_write_register(hwmgr->device, indirect_port, index);
-   return phm_wait_on_register(hwmgr, indirect_port + 1, mask, value);
+   return phm_wait_on_register(hwmgr, indirect_port + 1, value, mask);
 }

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

not_testable

swap-to-match-callee one-liner in finding markdown
per-fix-DF-4667

Confirmed kernel references

Detail

Exploit chain

[]

Evidence (decisive lines)

phm_wait_on_indirect_register passes (mask, value) to a (index, value, mask) callee - provable against the sibling at :185 which passes correctly. Latent argument-order hazard. Info/hardening; no pack.

Verdict

not_run: Info, latent-only (sole caller insensitive to the swap)