Divide-by-zero kernel panic in vega20_fan_ctrl_set_fan_speed_rpm via 8*speed uint32 wraparound
Summary
vega20_fan_ctrl_set_fan_speed_rpm (vega20_thermal.c:202) computes tach_period = 60 * crystal_clock_freq * 10000 / (8 * speed) entirely in 32-bit unsigned int. Only validation is speed!=0 (line 192). Speed values 0x20000000, 0x40000000, 0x60000000, 0x80000000, 0xA0000000, 0xC0000000, 0xE0000000 make 8*speed wrap to exactly 0 in uint32 -> #DE divide-by-zero trap -> kernel panic. Numerator also overflows uint32 for realistic xclk ~100MHz (60*100000*10000=6e10>4.29e9) corrupting tach period. Sibling smu7 guards speed > ulMaxRPM preventing this; vega20 omits bound entirely. Reachable via hwmon sysfs fan1_target write: amdgpu_hwmon_set_fan1_target (amdgpu_pm.c:1275) kstrtou32 no upper bound -> amdgpu_dpm_set_fan_speed_rpm -> pp_dpm_set_fan_speed_rpm (amd_powerplay.c:588 takes smu_lock) -> hwmgr_func->set_fan_speed_rpm. Attacker: user with write access to /sys/class/hwmon/hwmonN/ (root default; desktop/udev may grant video group); echo 1 > fan1_enable then echo 536870912 > fan1_target. AV:L/PR:L/AC:L, A:H.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2035 Β· 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | Source-confirmation verdict for DF-2035 | 681 B | β raw |
| fix.diff | suggested-fix | Guard 8*speed overflow/wrap-to-zero in set_fan_speed_rpm | 697 B | view raw |
| ../fix_build.log | build-log | Batch kernel build log (all fixes, rc=0) | 5.6 MB | β download |
DF-2035 Verification Verdict
Severity: Medium Impact class: panic Verification method: Source-only confirmation (HW-gated, not triggerable on QEMU guest)
Verdict: REPRODUCED (source-confirmed)
The bug is confirmed in the audited source at the cited path:line. HW-gated: requires specific hardware/driver (not present in QEMU guest) - cannot trigger at runtime.
Fix: Guard 8*speed overflow/wrap-to-zero in set_fan_speed_rpm
Fix applied and validated in batch kernel build (rc=0, -Werror).
Fix validation
All 41-fix patches batched into single make -j6 nativekernel KERNCONF=X86_64_GENERIC build.
Build result: rc=0, 0 errors (full -Werror clean).
Fix verification
fixedVALIDATED: fix.diff applies cleanly + batch kernel build rc=0 -Werror; bug HW/module/runtime-gated, no runtime PoC re-test possible on guest.
VALIDATED: fix.diff applies cleanly + batch kernel build rc=0 -Werror; bug HW/module/runtime-gated, no runtime PoC re-test possible on guest.
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
REPRODUCED (source-only): vega20_fan_ctrl_set_fan_speed_rpm computes tach_period = 60*crystal_clock_freq*10000/(8*speed) in uint32_t. Only validation is speed!=0; speed values around 0x20000000 cause
Verified recommended fix
REPRODUCED (source-only): vega20_fan_ctrl_set_fan_speed_rpm computes tach_period = 60crystal_clock_freq10000/(8*speed) in uint32_t. Only validation is speed!=0; speed values around 0x20000000 cause 32-bit overflow of numerator.
Verdict
REPRODUCED (source-only): vega20_fan_ctrl_set_fan_speed_rpm computes tach_period = 60crystal_clock_freq10000/(8*speed) in uint32_t. Only validation is speed!=0; speed values around 0x20000000 cause 32-bit overflow of numerator.
No comments yet.