Inverted error check at btc_dpm_init:2602-2607 β ATOM-computed PLL reference divider used only when radeon_atom_get_clock_dividers FAILS (default used on success)
Summary
'if (ret) pi->ref_div = computed; else pi->ref_div = default;' - success discards the computed divider and takes the default; failure programs ref_div=1 (no uninit read - callee memsets), shrinking MPLL lock time 12x. Correct pattern exists in ni_dpm.c. Hardware stability only. One-token fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3976 Β· 5 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.4 KB | β raw | |
| VERDICT.md | β | 1.1 KB | β raw | |
| verdict.json | β | 1.8 KB | view raw | |
| manifest.json | β | 470 B | view raw | |
| fix.diff | β | 312 B | view raw |
DF-3976 β Inverted error check in btc_dpm_init: computed PLL reference divider used only when radeon_atom_get_clock_dividers FAILS
- File:
sys/dev/drm/radeon/btc_dpm.c:2602-2607 - Class: CWE-670 wrong logic (Info) β family: DF-3652 (ci inverted return). Functional/hardening, no memory-safety impact.
Code
ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
0, false, ÷rs);
if (ret)
pi->ref_div = dividers.ref_div + 1; /* used on FAILURE */
else
pi->ref_div = R600_REFERENCEDIVIDER_DFLT; /* default on SUCCESS */
radeon_atom_get_clock_dividers() returns 0 on success; on failure it has already memset dividers
to zero (radeon_atombios.c:2838), so the failure arm programs pi->ref_div = 1, and the success arm
discards the computed dividers.ref_div. Compare the correct pattern in the same tree
(ni_dpm.c:2015-2020: if (ret) return ret; then use dividers).
Impact
pi->ref_div feeds MPLL lock-time programming (rv770_dpm.c:815,
MPLL_LOCK_TIME(R600_MPLLLOCKTIME_DFLT * pi->ref_div)): on an ATOM command failure the lock time is
programmed 12x too short (ref_div=1 vs default 12) β marginal memory-clock PLL locking / display
instability. No memory-safety impact (dividers is stack memory but pre-zeroed by the callee, so no
uninitialized read reaches it). Info severity, matching DF-3652's treatment of the analogous
inverted return.
VERDICT β DF-3976
status: inconclusive (hardware-gated Info-severity hardening finding; source-level certainty: certain about the inversion)
The inversion is self-evident against the sibling pattern in ni_dpm.c:2015-2020 and against
radeon_atom_get_clock_dividers' contract (returns 0 on success; memsets dividers at
radeon_atombios.c:2838 before any failure return). I verified there is no uninitialized-stack read
here (the callee zeroes the struct first), which is why this is CWE-670 Info and not CWE-457: the
only consequence is pi->ref_div = 0 + 1 = 1 on the failure arm and a discarded computed value on
the success arm, feeding MPLL_LOCK_TIME at rv770_dpm.c:815.
No runtime verification possible (no radeon GPU in the guest). fix.diff flips the condition to match the ni pattern.
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablefix.diff authored (condition flip); not runtime-testable without hardware.
findings/poc/DF-3976/fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
README.md code excerpt; ni_dpm.c:2015-2020 shows the correct pattern
PoC changes
No PoC (Info-severity logic inversion; nothing to reproduce without hardware).
Verified recommended fix
Invert the condition: use dividers.ref_div + 1 on success (!ret), default on failure.
Verdict
btc_dpm_init:2602-2607 uses the ATOM-computed ref_div only on the FAILURE arm of radeon_atom_get_clock_dividers and the hardcoded default on success β the condition is inverted relative to the ni_dpm.c:2015-2020 pattern. No uninit read (callee memsets dividers, radeon_atombios.c:2838); impact is a wrong pi->ref_div (1 on failure) feeding MPLL lock-time programming (rv770_dpm.c:815) β hardware-stability only. Info severity per DF-3652 precedent for inverted returns. Hardware-gated: not runtime-testable in the guest.
No comments yet.