Inverted error check at cypress_dpm_init:2059-2064 β ATOM engine-PLL reference divider used only on FAILURE (consuming uninitialized stack dividers), default used on success (cypress twin of DF-3976)
Summary
'if (ret) pi->ref_div = dividers.ref_div + 1; else pi->ref_div = default;' - on every board where the ATOM call SUCCEEDS (normal case) the computed divider is discarded and ref_div hardcoded; on failure the branch consumes the uninitialized stack dividers. Sink: MPLL lock-time programming - wrong memory-PLL lock timings on functional hardware, garbage-derived when the call fails. Upstream carries the identical inverted condition (checked vs torvalds master) - same basis as the btc twin DF-3976. One-token invert fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4119 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.2 KB | β raw | |
| VERDICT.md | β | 1.8 KB | β raw | |
| fix.diff | β | 514 B | view raw | |
| env.txt | β | 583 B | view raw | |
| manifest.json | β | 873 B | view raw | |
| verdict.json | β | 2.0 KB | view raw |
DF-4119 β Inverted error check in cypress_dpm_init: ATOM engine-PLL reference divider used only on FAILURE (twin of DF-3976) ===================================================================== File: sys/dev/drm/radeon/cypress_dpm.c:2059-2064 β pass 2 (GLM 5.3).
ret = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
0, false, ÷rs);
if (ret) /* inverted (DF-3976 twin) */
pi->ref_div = dividers.ref_div + 1; /* uninit stack on failure */
else
pi->ref_div = R600_REFERENCEDIVIDER_DFLT; /* default on SUCCESS */
- Normal hardware (call SUCCEEDS): computed divider discarded, ref_div hardcoded to 4.
- Failing call:
dividers(cypress_dpm.c:2029, stack) is consumed uninitialized -> garbage pi->ref_div. - Sink: rv770_dpm.c:815 MPLL_LOCK_TIME(R600_MPLLLOCKTIME_DFLT * pi->ref_div) and engine-speed parameter programming -> wrong memory PLL lock timings (functional, not memory-unsafe).
- Upstream Linux master carries the same inverted condition in
cypress_dpm.c AND btc_dpm.c (verified against torvalds/linux
2026-09-18); btc twin filed as DF-3976.
Hardware-gated; no security-relevant memory sink; Low.
FIX: fix.diff β
if (!ret)(one line).
DF-4119 VERDICT β inverted ref_div error check in cypress_dpm_init
STATUS: inconclusive (runtime hardware-gated); source certain, verified against upstream. impact: none (functional; wrong PLL lock timings / uninitialized-stack-derived value programmed to hardware). confidence: certain.
CHAIN:
* cypress_dpm.c:2059-2064 β if (ret) pi->ref_div = dividers.ref_div+1;
else pi->ref_div = R600_REFERENCEDIVIDER_DFLT;
* struct atom_clock_dividers dividers; at :2029 is UNINITIALIZED
stack; radeon_atom_get_clock_dividers does not fully populate it on
failure => the failure branch consumes garbage (also an
uninitialized-read defect, stack-info flows only into a register
value programmed to the GPU, never to userspace).
* The success branch (normal hardware) discards the ATOM-computed
divider and hardcodes 4.
* Sink: pi->ref_div at rv770_dpm.c:815
(MPLL_LOCK_TIME(R600_MPLLLOCKTIME_DFLT * pi->ref_div) inside
rv770's memory-PLL timing programming, shared by this dispatch).
* Upstream comparison (2026-09-18, torvalds/linux master):
cypress_dpm.c and btc_dpm.c BOTH carry if (ret) β upstream-shared
defect, exactly like the basis on which DF-3976 (btc twin) was
filed. DragonFly import (FreeBSD radeon port) inherits it.
FIX: fix.diff β invert to if (!ret). fix_status not_testable (no
hardware to validate programming against).
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_testableOne-line fix authored; validation requires evergreen hardware absent from the audit guest.
fix.diff
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md; fix.diff (one-line inversion); env.txt
PoC changes
No seed PoC; hardware-gated.
Verified recommended fix
Invert the check to if (!ret) (fix.diff).
Verdict
Source certain, upstream-verified, runtime hardware-gated. cypress_dpm.c:2059-2064 uses the ATOM-computed engine-PLL reference divider only when radeon_atom_get_clock_dividers FAILS (consuming the uninitialized stack dividers declared at :2029) and hardcodes R600_REFERENCEDIVIDER_DFLT (4) on success β inverted. Sink: pi->ref_div at rv770_dpm.c:815 MPLL_LOCK_TIME(R600_MPLLLOCKTIME_DFLT * pi->ref_div) and engine-speed parameter programming: wrong memory-PLL lock timings on all functional hardware, garbage-derived timings when the ATOM call fails. Upstream Linux master carries the identical inverted condition in cypress_dpm.c and btc_dpm.c (checked 2026-09-18), the same basis on which the btc twin DF-3976 was filed. Functional/uninitialized-stack-read-into-hw-programming defect; no kernel memory-safety sink.
No comments yet.