DF-5137 / verdict.json
{ "finding_id": "DF-5137", "status": "untested", "title": "kv_notify_message_to_smu() fail-open response validation in radeon kv_smc.c (twin of DF-5132): SMC timeout (0x0000) and all undefined response codes except 0x00FF/0x00FE reported as success to the kv_dpm power-management state machine", "verdict": "Statically certain logic defect, hardware-gated runtime: kv_notify_message_to_smu() (sys/dev/drm/radeon/kv_smc.c:30-52) validates the SMC response by rejecting only the literals 0xFF/0xFE (kv_smc.c:44-49), so a wait-loop timeout (resp 0x0000 = no response yet per radeon ppsmc.h:67 where OK==0x01) and every undefined code fall through to return 0 = success; because SMC_RESP_MASK is 0xffff (cikd.h:431) the literals only match 0x00FF/0x00FE, widening the hole vs the amdgpu twin (e.g. 0xFF00 byte-swapped FAILED also succeeds). The whole kv_dpm.c state machine (37 refs) then proceeds against a wedged SMC; kv_dpm_get_enable_mask (kv_smc.c:54-64) additionally reads the ARG register as a valid mask after a timed-out query. No attacker-controlled input, no memory-safety consequence (SRAM write path fails closed via kv_set_smc_sram_address:78-81 re-validation of 4-aligned addresses; outer u32 wrap at kv_smc.c:125 cannot smuggle an OOB write), ceiling is PM desync/GPU hang on already-faulted silicon -> Info. Runtime not reproducible on the audit guest (zero AMD/ATI PCI devices); honest status untested with 11/11 mechanical static assertions in check_static.log, including the same-driver contrast where si_smc.c:190 and rv770_smc.c:446 return the raw (PPSMC_Result)tmp so their callers DO observe timeouts as failures.", "reproduced": false, "impact": "none", "confidence": "certain", "exploit_chain": "", "evidence": "check_static.log: 11/11 PASS incl. kv_fallthrough_ret0 (return 0 reachable with tmp==0), resp_mask_is_16bit (cikd.h:431 = 0xffff), si_returns_raw/rv770_returns_raw contrast, getmask_reads_arg; fix.diff hunk @@ -41,11 +41,10 @@ replacing the 0xFF/0xFE whitelist with tmp != PPSMC_Result_OK rejection; VERDICT.md records the fail-closed kill of the adjacent kv_smc.c:125 u32-wrap candidate (inner re-validation at :78-81, same analysis DF-5132 applied to the amdgpu twin); fix_build.log = full radeon.ko -Werror build with the fix applied on the guest /usr/src", "kernel_refs": [ "sys/dev/drm/radeon/kv_smc.c:30-52", "sys/dev/drm/radeon/kv_smc.c:44-51", "sys/dev/drm/radeon/kv_smc.c:54-64", "sys/dev/drm/radeon/ppsmc.h:67-68", "sys/dev/drm/radeon/cikd.h:429-431", "sys/dev/drm/radeon/si_smc.c:172-190", "sys/dev/drm/radeon/rv770_smc.c:424-448", "sys/dev/drm/radeon/kv_dpm.c:451-471", "sys/dev/drm/radeon/kv_smc.c:125", "sys/dev/drm/radeon/kv_smc.c:78-81" ], "poc_changes": "no seed PoC existed (twin filed during pass 2); authored check_static.sh with 11 mechanical assertions against the tree since no runtime trigger is possible without Kaveri APU hardware; fix.diff mirrors the accepted DF-5132 fix shape adapted to radeon identifiers (dev_err(rdev->dev,...), PPSMC_Result_OK in scope via kv_dpm.h:32 -> ppsmc.h)", "attempts": 1, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64 (guest up, zero AMD/ATI PCI devices)", "runtime_sec": 3, "guest_dirty": 0, "build_cmd": "static proof: sh findings/poc/DF-5137/check_static.sh /home/maxx/dfbsd/dfbsd ; fix compile-validation: (cd /usr/src/sys/dev/drm/radeon && make) on the guest with fix.diff applied", "run_cmd": "sh findings/poc/DF-5137/check_static.sh /home/maxx/dfbsd/dfbsd", "code_hash": "baf86917f9190c445b0a52cbe55380e0f39d44f998c20293b5fdee489d533bba", "notes": "Radeon-side twin of DF-5132 (amdgpu kv_smc.c:33-55) which explicitly anticipated it; independent of known DF-2135 (missing smc_idx_lock, the serialization issue, not the validator). Raven-specific widening vs the twin: SMC_RESP_MASK=0xffff makes the rejection set {0x00FF,0x00FE} of 65536 codes. Killed adjacent candidate: kv_smc.c:125 outer u32 wrap fails closed (inner kv_set_smc_sram_address re-validation :78-81, alignment gate makes wrap impossible there); wait loop bounded by usec_timeout=100000 (radeon_device.c:1300, radeon.h:131).", "recommended_fix": "Reject every response != PPSMC_Result_OK (return -EINVAL with a dev_err identifying the message and response) instead of whitelisting only 0xFF/0xFE \u2014 see fix.diff", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 x86_64", "fix_verdict": "runtime fix validation not applicable: no runtime baseline can exist on the QEMU audit guest (no AMD GPU) and the defect requires a stalled Kaveri SMC to manifest. Compile validation performed instead: fix.diff applied to the guest /usr/src and radeon.ko rebuilt with -Werror \u2014 clean build, kv_smc.o linked (fix_build.log, 170 lines). fix.diff verified git-apply-clean against the unmodified repo tree and uses PPSMC_Result_OK already in scope via kv_dpm.h:32 -> ppsmc.h, dev_err via linux/device.h:67", "fix_evidence": "fix_build.log (full radeon.ko build output with the fix applied, exit 0); git apply --check findings/poc/DF-5137/fix.diff => clean; hunk @@ -41,11 +41,10 @@ sys/dev/drm/radeon/kv_smc.c" } |