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

Divide-by-zero panic in tonga_thermal_setup_fan_table from VBIOS fan temperatures (usTMed==usTMin or usTHigh==usTMed)

Summary

The function computes t_diff1/t_diff2 from values copied verbatim out of the VBIOS fan table (no distinctness/ordering validation) and divides by both for the slopes. Existing guards do not check the deltas. A crafted VBIOS with equal adjacent temperature points triggers a #DE kernel panic at DPM enable. Known DF-1274 covered only the SS rates; tonga was the missing member of the sibling-driver fan-div0 family (DF-1297/1323/1325/1345). VERIFIED: guest harness performs the identical division and faults SIGFPE rc=132. Guard-deltas fix (the accepted fiji shape).

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3910 Β· 11 files
FileTypeDescriptionSize
trigger_analysis.c trigger-source userspace demonstrator of the kernel index/pointer/division arithmetic 2.1 KB view raw
build.sh build-script cc build of the demonstrator 65 B view raw
run.sh run-script runs the demonstrator 89 B view raw
build.log build-log guest compiler output 11 B view raw
run.log run-log guest runtime output (decisive run) 218 B view raw
env.txt environment guest uname + pciconf (no AMD GPU / no MPT HBA) 838 B view raw
fix.diff suggested-fix git-apply-able unified diff 664 B view raw
fix_build.log build-log fix apply + nativekernel rebuild summary, rc=0 -Werror 6.3 KB view raw
VERDICT.md verdict full verification narrative 2.1 KB ↓ raw
README.md readme human-readable summary 1.7 KB ↓ raw
../DF-3908/fix_kernel_full.log build-log full nativekernel build log shared from DF-3908 pack 5.6 MB ↓ download
README.md readme human-readable summary
↓ download raw

DF-3910 β€” Tonga fan-table slope divide-by-zero (usTMed == usTMin) β†’ kernel #DE panic

File: sys/dev/drm/amd/powerplay/smumgr/tonga_smumgr.c Lines: 2502-2513 (tonga_thermal_setup_fan_table) Severity: Medium (local DoS at GPU/DPM enable) β€” hardware-gated (Tonga/Fiji + crafted VBIOS fan table) Class: base:dev / CWE-369 (divide-by-zero), pass 2 (the fan table β€” not covered by DF-1274, which fixed only SCLK/MCLK SS rates at :591/:883)

Build / Run

./build.sh && ./run.sh

Expected output

duty100=200 pwm_diff1=1234 usTMin=4000 usTMed=4000 -> t_diff1=0
evaluating (50 + ((16 * duty100 * pwm_diff1) / t_diff1)) / 100 ...
Illegal instruction (core dumped)          <- SIGFPE == kernel #DE
trigger rc=132 (42 == SIGFPE/#DE fault demonstrated)

(The userspace division raises SIGFPE exactly the way the kernel path raises a divide-error fault β†’ panic. run.log on the guest shows the actual fault.)

Root cause

process_pptables_v1_0.c:941-986 copies usTMin/usTMed/usTHigh verbatim from the VBIOS fan table with no distinctness check. tonga_thermal_setup_fan_table computes t_diff1 = usTMed - usTMin (:2502-2503), t_diff2 = usTHigh - usTMed (:2504-2505) and divides by both at :2512-2513 without a zero check. A crafted VBIOS with usTMed == usTMin (or usTHigh == usTMed) panics the kernel during DPM enable (MicrocodeFanControl cap set, fan present, duty100 != 0 β€” all satisfied on real fan-equipped boards).

Fix

fix.diff adds the same guard the sibling drivers' fixes use (cf. DF-1297 ci, DF-1323 iceland, DF-1325 fiji, DF-1345 polaris10): if either delta is zero, unset PHM_PlatformCaps_MicrocodeFanControl and return 0. Validated in the batch nativekernel rebuild: rc=0, -Werror clean (fix_build.log).

VERDICT.md verdict full verification narrative
↓ download raw

DF-3910 β€” Verification Verdict

Status: inconclusive (reproduced=0) Impact: none on guest (no AMD GPU); userspace harness faults exactly as predicted Confidence: certain (source-level; arithmetic fault demonstrated)

Finding

tonga_thermal_setup_fan_table() divides by VBIOS-supplied temperature deltas with no zero check:

t_diff1 = usTMed - usTMin;            tonga_smumgr.c:2502
t_diff2 = usTHigh - usTMed;           :2504
slope1 = (50 + ((16*duty100*pwm_diff1)/t_diff1)) / 100;   :2512  <-- div by 0
slope2 = (50 + ((16*duty100*pwm_diff2)/t_diff2)) / 100;   :2513  <-- div by 0

usTMin/usTMed/usTHigh come straight from ATOM_Tonga_Fan_Table / ATOM_Fiji_Fan_Table (process_pptables_v1_0.c:941-946 / 978-982) with no validation. Guards present: MicrocodeFanControl cap (:2472), bNoFan (:2476), fan_table_start (:2482), duty100==0 (:2492) β€” none check the deltas.

Verification

  • Source chain certain (above).
  • Guest run (run.log): the identical expression with usTMed==usTMin raises SIGFPE ("Illegal instruction (core dumped)", rc=132) β€” the userspace analogue of the kernel #DE panic. Kernel-path execution requires Tonga/Fiji hardware (absent β€” env.txt), hence inconclusive, matching the DF-1274 precedent (the SCLK/MCLK SS div0 twin, poc status inconclusive).

Fix validation

Guard added after the t_diff2 computation: zero delta β†’ unset MicrocodeFanControl, return 0 (identical to the accepted fiji fix DF-1325). Batch nativekernel rebuild on guest: tonga_smumgr.c compiled -Werror clean, kernel rc=0 (fix_build.log). fix_status = fixed (compile-validated).

Distinct from knowns

DF-1274 = spread-spectrum rates (speed_spectrum_rate==0) at :591/:883 β€” different inputs, different sites; fan-table slopes were not covered.

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

fixed
baseline no→ patch + rebuild →patched clean

fixed (compile-validated): fix.diff applied to clean guest /usr/src with the batch; nativekernel rebuild rc=0, 0 errors; tonga_smumgr.c compiled with -Werror (full log in DF-3908 pack, line 28191). Runtime re-test impossible on this guest (no AMD GPU).

fix_build.log (apply + compile lines + NK_DONE rc=0); run.log (SIGFPE on zero delta); full build log shared from DF-3908/fix_kernel_full.log.
↓ fix.diffDragonFly dfbsd 6.5-DEVELOPMENT (nativekernel, patched, rc=0, -Werror clean)

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log on guest: 'Illegal instruction (core dumped)' from the t_diff1==0 division; VERDICT.md source chain; fix_build.log (-Werror compile of patched file)

PoC changes

Pass-2 reviewer authored trigger/analysis + fix from source; harness built and run on the DragonFly guest (SIGFPE observed); fix compile-validated via full nativekernel rebuild.

Verified recommended fix

Guard t_diff1/t_diff2 == 0: unset PHM_PlatformCaps_MicrocodeFanControl and return 0 (identical to DF-1325 fiji fix).

Verdict

Source-certain divide-by-zero: tonga_thermal_setup_fan_table() divides by t_diff1=usTMed-usTMin / t_diff2=usTHigh-usTMed taken verbatim from the VBIOS fan table (process_pptables_v1_0.c:941-986, no distinctness validation); usTMed==usTMin gives #DE panic at DPM enable. Guest harness performs the identical division and faults with SIGFPE (rc=132), the exact userspace analogue; kernel path hardware-gated. DF-1274 covered only SCLK/MCLK SS rates; fan slopes are the uncovered twin (per-file twins DF-1297/1323/1325/1345).