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

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-1151 Β· 8 files
FileTypeDescriptionSize
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
README.md readme human reproduce doc
↓ download 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 in kernel.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.

VERDICT.md verdict Full source trace + reachability analysis (radeon twin of DF-1143)
↓ download raw

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.

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_testable

git 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.