Divide-by-zero DoS in ci_thermal_setup_fan_table from unvalidated VBIOS fan temperatures
Summary
ci_thermal_setup_fan_table at ci_dpm.c:1018-1025: t_diff1=fan.t_med-fan.t_min and t_diff2=fan.t_high-fan.t_med from VBIOS u16 used as divisors with no zero check. If t_med==t_min or t_high==t_med: integer divide-by-zero -> kernel #DE panic during DPM enable. Reached at every boot/resume. Attacker: malicious VBIOS via reflash/PCIe/QEMU. Same class as DF-1129/1137/1143. Fix: validate deltas non-zero.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1151 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | Full source trace + reachability analysis (radeon twin of DF-1143) | 2.4 KB | β raw |
| fix.diff | suggested-fix | Guard zero deltas before divide (git apply-able, validated) | 528 B | view raw |
| build.sh | build-doc | Documents why no executable PoC is possible | 329 B | view raw |
| run.sh | run-doc | Documents why runtime trigger is impossible on this guest | 176 B | view raw |
| env.txt | environment | uname + kernel symbol inventory proving radeon absent | 343 B | view raw |
| README.md | readme | human reproduce doc | 726 B | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1151 β divide-by-zero in radeon ci_thermal_setup_fan_table
Result
NOT REPRODUCED on this guest. Real source-level defense-in-depth bug;
fix authored. This is the radeon twin of DF-1143. See VERDICT.md for
the full analysis.
Build & run
./build.sh # documents why no executable PoC is possible ./run.sh # documents why runtime trigger is impossible
Reachability summary
- radeon is not in
X86_64_GENERIC(0 symbols inkernel.debug) - No AMD GPU on the QEMU guest
- Attacker model is malicious VBIOS, not unprivileged local
Fix
fix.diff β guard zero t_diff1/t_diff2 before the divide at
sys/dev/drm/radeon/ci_dpm.c:1024-1025. Applies cleanly with
git apply.
DF-1151 β divide-by-zero in ci_thermal_setup_fan_table (radeon)
Verdict
NOT REPRODUCED on this guest (defense-in-depth source bug confirmed; path
unreachable on the default GENERIC DragonFlyBSD kernel running in QEMU).
Real source-level defect; fix.diff authored. This is the radeon-driver twin
of DF-1143 (the same defect exists in both sys/dev/drm/radeon/ci_dpm.c and
sys/dev/drm/amd/amdgpu/ci_dpm.c, which were forked from a common ancestor).
Mechanism (source trace, bug confirmed real)
In sys/dev/drm/radeon/ci_dpm.c:991, ci_thermal_setup_fan_table() computes
the fan PWM slope from three VBIOS-supplied u16 temperatures:
/* sys/dev/drm/radeon/ci_dpm.c:1018-1025 */
t_diff1 = rdev->pm.dpm.fan.t_med - rdev->pm.dpm.fan.t_min; /* L1018 */
t_diff2 = rdev->pm.dpm.fan.t_high - rdev->pm.dpm.fan.t_med; /* L1019 */
...
slope1 = (u16)((50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100); /* L1024 */
slope2 = (u16)((50 + ((16 * duty100 * pwm_diff2) / t_diff2)) / 100); /* L1025 */
The temperatures are populated directly from the AtomBIOS PowerPlay table
(sys/dev/drm/radeon/r600_dpm.c:897-899):
rdev->pm.dpm.fan.t_min = le16_to_cpu(fan_info->fan.usTMin);
rdev->pm.dpm.fan.t_med = le16_to_cpu(fan_info->fan.usTMed);
rdev->pm.dpm.fan.t_high = le16_to_cpu(fan_info->fan.usTHigh);
A VBIOS image with usTMin == usTMed or usTMed == usTHigh makes the kernel
divide by zero at L1024/L1025 β #DE β panic during DPM enable.
Why it does NOT reproduce on this guest
Same reasons as DF-1143:
1. radeon driver is not in the GENERIC kernel. grep radeon
sys/config/X86_64_GENERIC is empty; the driver ships only as
radeon.ko (and ~150 radeonkmsfw_.ko firmware modules).
nm /boot/kernel/kernel.debug | grep -ciE 'radeon|amdgpu' β 0.
No radeon module is loaded on the running guest.
2. No AMD GPU in the QEMU guest (serial-console VM, no PCI GPU).
3. Threat model is malicious-VBIOS*, not unprivileged local.
Exploit chain
none β primitive (kernel #DE / DoS) requires AMD hardware + module load + attacker-controlled VBIOS, none of which exist on this guest.
PoC changes
none β no executable PoC is possible; the path is dead code in the running kernel and depends on hardware this guest does not have.
Recommended fix
Mirror the DF-1143 fix: guard zero deltas before the divide. See fix.diff
β applies cleanly with git apply (validated). Matches the finding
markdown's proposal.
Fix verification
not_testablegit apply --check validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. Same bug in radeon ci_dpm.c. Twin of DF-1143.
No comments yet.