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

Second divide-by-zero window in cypress_populate_mclk_value: clk_s truncating to 0 makes (clk_s * 625) a zero divisor at :567 (sibling of DF-1387, different expression and condition)

Summary

DF-1387 covers only ss.rate==0 at the first division. Even with rate != 0, u32 truncation of clk_s = reference_clock*5/(decoded_ref*ss.rate) yields 0 whenever decoded_ref*ss.rate > reference_clock*5, and the second division divides by clk_s*625 == 0 -> #DE panic. All inputs VBIOS-controlled; worked panic tuples (2700,2,6751), (10000,2,25001). Reachable at DPM enable and every power-state change when memory-clock SS support exists - same gating as accepted DF-1387. Expression byte-identical upstream. Zero-check-the-quotient fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4120 Β· 6 files
FileTypeDescriptionSize
README.md β€” 1.5 KB ↓ raw
VERDICT.md β€” 2.5 KB ↓ raw
fix.diff β€” 2.1 KB view raw
env.txt β€” 583 B view raw
manifest.json β€” 920 B view raw
verdict.json β€” 2.6 KB view raw

DF-4120 β€” Second divide-by-zero in cypress_populate_mclk_value: clk_s == 0 makes (clk_s * 625) a zero divisor at :567 ===================================================================== File: sys/dev/drm/radeon/cypress_dpm.c:565-567 β€” pass 2 (GLM 5.3). Sibling of known DF-1387 (ss.rate == 0 at :565, lines 553-565) β€” different expression, different condition, same VBIOS family.

clk_s = reference_clock * 5 / (decoded_ref * ss.rate);   (:565)
clk_v = ss.percentage * (...) / (clk_s * 625);           (:566-567)

Integer truncation: decoded_ref * ss.rate > reference_clock * 5 => clk_s = 0 => #DE kernel panic at :567. * ss.rate: raw u16 usSpreadRateInKhz (radeon_atombios.c:1546, max 65535) β€” DF-1387 only excludes rate == 0. * decoded_ref: 1..~15 (rv740_get_decoded_reference_divider). * reference_clock: rdev->clock.mpll.reference_freq (10 kHz units; 10000 typical, 2700 on 27 MHz-reference boards). Example values that panic: ref=2700, decoded_ref=2, rate=6751; ref=10000, decoded_ref=2, rate=25001. Reachable when pi->mclk_ss && ASIC_INTERNAL_MEMORY_SS entry matches (cypress_convert_power_level_to_smc -> cypress_populate_mclk_value, i.e. DPM enable and every power-state change on the affected level). Crafted-VBIOS panic, same acceptance basis as DF-1386/1387 ("no zero check upstream" β€” expression identical in Linux master). Hardware-gated on the audit guest; runtime inconclusive; arithmetic certain. FIX: fix.diff β€” bail out when clk_s truncates to 0.

VERDICT.md
↓ download raw

DF-4120 VERDICT β€” clk_s==0 divide-by-zero at cypress_dpm.c:567

STATUS: inconclusive (runtime hardware-gated); arithmetic certain. impact ceiling (not demonstrated): #DE kernel panic at DPM enable / power-state change. confidence: likely.

CHAIN: * cypress_populate_mclk_value, pi->mclk_ss branch: :565 clk_s = reference_clock * 5 / (decoded_ref * ss.rate); :566 clk_v = ss.percentage * (0x4000whole_fb_div + 0x800frac_fb_div) / (clk_s * 625); * DF-1387 (known, lines 553-565) guards only the rate==0 form of the FIRST division. Even with rate > 0, u32 truncation of :565 yields clk_s == 0 whenever decoded_refss.rate > reference_clock5, and the SECOND division at :567 divides by clk_s*625 == 0 => #DE. * Attacker/VBIOS-controlled inputs: ss.rate raw u16 usSpreadRateInKhz (radeon_atombios.c:1546) decoded_ref 1..~15 (rv740_get_decoded_reference_divider, rv740_dpm.c: encoded 0->1, 16->2, 17->3, ...) reference_clock rdev->clock.mpll.reference_freq (10 kHz units; 10000 typical, 2700 on 27 MHz reference boards) Worked panic examples: (2700, 2, 6751), (10000, 2, 25001), (10000, 1, 50001). * Reachability: cypress_convert_power_level_to_smc:728-741 -> cypress_populate_mclk_value during cypress_dpm_enable:1878 (cypress_init_smc_table -> initial state) and every cypress_dpm_set_power_state:1979 (cypress_upload_sw_state). Preconditions: ATOM_BIOS_INFO_MEMORY_CLOCK_SS_SUPPORT firmware flag, pi->mclk_ss true (rv770_get_engine_memory_ss), and a matching ASIC_InternalSS_Info entry. Same gating as accepted DF-1387. * Real-VBIOS plausibility: spread rates that large are physically nonsensical for real SS silicon (hence 'likely', not 'certain' as a field bug) but trivially craftable in a flashed/virtual option ROM β€” identical acceptance basis to DF-1386/DF-1387. * Expression is byte-identical in upstream Linux (verified against torvalds master 2026-09-18) β€” upstream-shared defect.

FIX: fix.diff β€” if (clk_s == 0) return -EINVAL; between the two divisions. fix_status not_testable (no hardware).

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_testable
baseline no→ patch + rebuild →patched clean

Diff authored; validation requires evergreen hardware absent from the audit guest.

fix.diff
↓ fix.diffper-fix-DF-4120

Confirmed kernel references

Detail

Exploit chain

Crafted VBIOS ss.rate (25-50+ MHz range, physically implausible for real SS silicon, trivially craftable in an option-ROM/vBIOS image) on an evergreen-family card with memory-clock SS support -> #DE panic at radeon attach/state-switch.

Evidence (decisive lines)

VERDICT.md (arithmetic + worked examples); fix.diff (clk_s==0 bail-out); env.txt

PoC changes

No seed PoC; hardware-gated.

Verified recommended fix

Return -EINVAL when clk_s truncates to 0 between the two divisions (fix.diff); complements the DF-1387 rate==0 guard.

Verdict

Arithmetic certain, field plausibility 'likely', runtime hardware-gated. cypress_populate_mclk_value's second spread-spectrum division (cypress_dpm.c:566-567) divides by clk_s625; clk_s (computed at :565 as reference_clock5/(decoded_refss.rate)) truncates to 0 whenever decoded_refss.rate > reference_clock*5, turning :567 into a divide-by-zero (#DE kernel panic) even with ss.rate != 0 β€” a different expression and condition from known DF-1387 (rate==0 at :565). Inputs are VBIOS-controlled: ss.rate raw u16 usSpreadRateInKhz (radeon_atombios.c:1546), decoded_ref 1..~15 (rv740_get_decoded_reference_divider), reference_clock = mpll.reference_freq (10000 typical, 2700 on 27 MHz boards). Panic examples: (2700,2,6751), (10000,2,25001), (10000,1,50001). Reachable at DPM enable and every power-state change when mclk_ss + matching ASIC_INTERNAL_MEMORY_SS entry exist β€” same gating as accepted DF-1387. Expression byte-identical in upstream Linux (checked 2026-09-18).