โฌข DragonFlyBSD Kernel Audit
DF-5206 / analysis.txt
โ† back to finding โ†“ download raw
DF-5206 annotated walkthrough โ€” trinity_acquire_mutex() void fail-open
Audit target: sys/dev/drm/radeon/trinity_smc.c (DragonFlyBSD pass 2, GLM 5.3)

[L112] void trinity_acquire_mutex(struct radeon_device *rdev)
       VOID return: a failed mutex acquisition is UNREPORTABLE by construction.
       Unique to Trinity in the radeon SMC family: si/ci/sumo/kv have no
       host-side SMC-mutex grant wait in their *_smc.c files (checked:
       rg acquire_mutex over sys/dev/drm/radeon/ -> only trinity files).
[L116] WREG32(SMC_INT_REQ, 1);
       Register 0x220 (trinityd.h:167). This is the host->SMC mutex REQUEST.
[L117-121] for (i = 0; i < rdev->usec_timeout; i++) {
               if ((RREG32(SMC_INT_REQ) & 0xffff) == 1) break;
               udelay(1);
           }
       Poll for grant, up to RADEON_MAX_USEC_TIMEOUT = 100000 us = 100 ms
       (radeon.h:131, set at radeon_device.c:1300). On timeout the loop just
       exits โ€” no error latch, no retry, no warning.
[L122] }
       Falls out with the mutex NOT held and the caller none the wiser.

Callers that then program SMC state assuming exclusivity (trinity_dpm.c):
  :1099  trinity_dpm_enable_bapm      (acquire; bapm_enable msg; release)
  :1109  trinity_dpm_enable           (acquire; full DPM enable program; release)
  :1138  trinity_dpm_late_enable      (acquire; clock/power gating; release)
  :1158  trinity_dpm_disable          (acquire; full DPM teardown; release)
  :1258  trinity_dpm_set_power_state  (acquire; power-state transition; release)
  :1288  trinity_dpm_setup_asic       (acquire; sstp/smu-control init; release)
  :1300  inside #if 0 (dead code, left untouched by fix.diff)

Contrast within the same file: trinity_notify_message_to_smu at least has an
int return (it merely validates fail-open โ€” that is DF-5205); the mutex grant
cannot even be checked by callers. And contrast ni.c:41-58: the indirect SMC
SRAM accessors tn_smc_rreg/tn_smc_wreg DO take rdev->smc_idx_lock, so the
DF-2135 class (missing kernel-side idx lock) is NOT present on TN โ€” the gap
here is host-vs-SMC-firmware exclusivity, which smc_idx_lock does not cover.

Security assessment: reliability fail-open on a hardware wait; no unprivileged
trigger, no attacker-controlled data, no memory-safety primitive. Info severity.

Fix (see fix.diff): int trinity_acquire_mutex() returning 0/-ETIME (backing off
the request on failure), prototype updated in trinity_dpm.h, all six live call
sites in trinity_dpm.c bail out on failure.