⬢ DragonFlyBSD Kernel Audit
DF-3613 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3613",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "Distinct div0 sink from DF-1137/DF-3612. radeon_atom_get_clock_info stores usCoreReferenceClock/usMemoryReferenceClock into spll/mpll.reference_freq with no zero fallback (pll_out_min gets a 64800/20000 default at radeon_atombios.c:1202, the reference clocks do not). si_calculate_sclk_params:4811 does do_div(tmp, reference_clock) for EVERY performance level of every power state (and 256x from si_init_smc_spll_table:2866) during si_dpm_enable; si_populate_mclk_value:4927 divides freq_nom by the mpll reference. reference_freq==0 -> #DE -> panic on the first level upload. Harness executes the exact 64-bit division in a forked child: SIGFPE == kernel #DE panic.",
  "exploit_chain": "crafted VBIOS FirmwareInfo with usCoreReferenceClock (or usMemoryReferenceClock) == 0 -> first si_populate_sclk_value at DPM enable -> do_div by 0 -> #DE -> panic (boot-time DoS)",
  "evidence": "run.log [A1]: child died from SIGFPE (signal 4): 64-bit divide by zero at :4811 replica; [A2] same at :4927; [B]: ref=0 -> rc=-1 (level upload refused, no trap); ref=27000 -> rc=0, fbdiv=114081",
  "kernel_refs": [
    "sys/dev/drm/radeon/si_dpm.c:4811",
    "sys/dev/drm/radeon/si_dpm.c:4927",
    "sys/dev/drm/radeon/radeon_atombios.c:1189",
    "sys/dev/drm/radeon/radeon_atombios.c:1216"
  ],
  "poc_changes": "n/a (pass-2 finding authored with its harness; no seeded PoC to fix)",
  "attempts": 2,
  "guest_uname": "DragonFly dfbsd 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": 90,
  "guest_dirty": 0,
  "build_cmd": "cd findings/poc/DF-3613 && sh build.sh",
  "run_cmd": "cd findings/poc/DF-3613 && sh run.sh",
  "code_hash": "191031737dbf53596b2f789ed0cc13ef6121116e7eb0d8cbf1c5d5d6a8775188",
  "notes": "Harness-level reproduction (exact kernel expressions executed with crafted-VBIOS inputs; SIGSEGV/SIGFPE/corruption observed). No AMD SI GPU on the virtio-only QEMU guest -> no live radeon DPM path possible; radeon.ko present at /boot/kernel. Guest /usr/src restored to pristine (sha 774b9b851b3b4ccb...) after fix validation.",
  "recommended_fix": "see fix.diff",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "git apply --check OK (standalone and stacked with the other four si_dpm.c fixes); targeted module TU compile `make KERNBUILDDIR=/usr/obj/usr/src/sys/X86_64_GENERIC si_dpm.o` => rc=0, -Werror clean (87080 B). Harness fixed-path shows the primitive gone (fix.diff adds `if (reference_clock == 0) return -EINVAL;` in si_calculate_sclk_params and si_populate_mclk_value. git apply --check OK; stacked module TU compile -Werror clean; harness [B] no trap, sane-clock path unchanged.)",
  "fix_evidence": "fix.diff adds `if (reference_clock == 0) return -EINVAL;` in si_calculate_sclk_params and si_populate_mclk_value. git apply --check OK; stacked module TU compile -Werror clean; harness [B] no trap, sane-clock path unchanged."
}