DF-4583 / verdict.json
{ "finding_id": "DF-4583", "status": "inconclusive", "reproduced": 0, "impact": "panic", "confidence": "likely", "verdict": "Two VBIOS-derived zero-divisor sinks in rs690_crtc_bandwidth_compute() panic the kernel via dfixed_div: (1) igp_sideport_mclk==0 (copied verbatim from the VBIOS IntegratedSystemInfo ulBootUpSidePortClock/ulBootUpMemoryClock by rs690_pm_info, no zero fallback) with sideport reported present divides by zero at rs690.c:371-372; (2) ulDefaultEngineClock==0 gives rdev->pm.sclk==0 and a zero max_bandwidth that every && bandwidth.full guard preserves, dividing by zero at rs690.c:386-388. Evidence: -O0 verbatim harness kills both scenarios with SIGFPE (run.2.log); the SHIPPED /boot/kernel/radeon.ko contains the runtime division for sink 1 (0x5adac-0x5adb9: r8=(mclk<<16)>>12, div %r8 \u2014 zero exactly when mclk==0) proving the real binary does not fold it away; the WITH_FIX harness build guards both sinks and survives. End-to-end execution needs RS690-class hardware with the crafted VBIOS (absent in the QEMU guest), and the KLD harness scenario-1 happened to be UB-transformed by gcc in that build context (documented), so overall status is inconclusive/likely rather than reproduced.", "exploit_chain": "crafted/corrupt GPU VBIOS (option-ROM reflash or malicious card) -> rs690_pm_info parses IntegratedSystemInfo with sideport-present flag and zero boot clocks (rs690.c:80/94/164) or radeon_atombios_get_clock_info stores default_sclk=0 (radeon_atombios.c:1240-1241, no zero fallback unlike :1269-1271) -> first bandwidth update (boot modeset / pm profile change) -> rs690_crtc_bandwidth_compute divides by the zero fixed-point value (rs690.c:371-372 or :386-388) -> do_div by zero -> integer divide fault -> kernel panic.", "evidence": "../DF-4582/run.2.log (SIGFPE x2 for scenarios 1 and 2 at -O0); ../DF-4582/objdump_radeon_ko.txt (0x5adb9 div %r8, divisor r8=(mclk<<16)>>12 == 0 iff mclk==0, in the shipped binary); ../DF-4582/fix_run.log (zero divisor avoided at rdl-mclk / 1000/sclk with survival and clean unload in the guarded build); fix.diff in this pack.", "kernel_refs": [ "sys/dev/drm/radeon/rs690.c:64-146", "sys/dev/drm/radeon/rs690.c:164", "sys/dev/drm/radeon/rs690.c:363-382", "sys/dev/drm/radeon/rs690.c:384-397", "sys/dev/drm/radeon/radeon_atombios.c:1240-1241", "sys/dev/drm/radeon/radeon_atombios.c:1269-1271", "sys/dev/drm/include/drm/drm_fixed.h:62-70" ], "poc_changes": "No seed; shares the DF-4582 harness (scenarios 1 and 2 map to the two sinks).", "attempts": 2, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC x86_64", "runtime_sec": 900, "guest_dirty": 0, "build_cmd": "cd ../DF-4582 && cc -O0 -o rs690_div0 rs690_div0.c", "run_cmd": "./rs690_div0 1 ; ./rs690_div0 2", "code_hash": "7db3b1ea1c4fbc19fd22e08d6da8ff7f30a18d3db699a5d8c1388923b1350856", "fix_status": "inconclusive", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "Guard-level validation only: the WITH_FIX harness build demonstrably avoids both zero divisors (DF4582-FIX: zero divisor avoided at rdl-mclk / 1000/sclk) and survives, and the guards are value-based (independent of how the zero arises). The unpatched KLD harness did not panic on scenario 1 in its particular -O2 codegen (gcc UB-transformed that chain there \u2014 see DF-4582 VERDICT), while the shipped radeon.ko disassembly (0x5adb9) proves the real binary keeps the runtime division, so a hardware baseline was not executable and fix_status is honestly inconclusive rather than fixed.", "fix_evidence": "fix.diff (zero sideport mclk treated as no-sideport with UMA latency + zero max_bandwidth bail); ../DF-4582/fix_run.log.", "notes": "Threat model is crafted/corrupt VBIOS or broken BIOS data (same model as the DF-4337 atom-family findings); availability impact only. The igp_system_mclk field already has a zero fallback (rs690.c:96-101) \u2014 the sideport and engine clocks simply lack the same treatment.", "recommended_fix": "rs690.c: treat igp_sideport_mclk==0 as no sideport (UMA read-delay latency) and bail with the safe watermark when max_bandwidth (pm.sclk-derived) is zero; optionally add zero fallbacks where radeon_atombios_get_clock_info stores default_sclk/default_mclk." } |