⬢ DragonFlyBSD Kernel Audit
DF-3610 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-3610",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "panic",
  "confidence": "certain",
  "verdict": "radeon twin of amdgpu DF-3586. rdev->pm.dpm.boot_ps is set ONLY in si_parse_pplib_non_clock_info() (si_dpm.c:6726-6727) when a VBIOS power state carries ATOM_PPLIB_CLASSIFICATION_BOOT. A crafted VBIOS with no such state (or ucNumEntries==0, which also yields a ZERO_SIZE_PTR dpm.ps that passes the !ps check at :6842) leaves boot_ps==NULL while si_parse_power_table returns 0. radeon_pm.c:1448 IGNORES the dpm.init return, :1449 assigns current_ps=requested_ps=boot_ps, and radeon_dpm_enable -> si_dpm_enable dereferences it: first fault at si_populate_smc_initial_state:4372 via ni_get_ps(NULL)->ps_priv (offset 0x28). Harness executes the exact chain in a forked child: SIGSEGV at 0x28 == kernel NULL-deref panic during DPM enable (boot-time DoS with malicious VBIOS). No live GPU trigger possible on the virtio-only audit guest; module radeon.ko present.",
  "exploit_chain": "crafted VBIOS (no BOOT state) -> si_parse_power_table OK -> radeon_pm_init_dpm ignores rc -> si_dpm_enable -> si_init_smc_table -> si_populate_smc_initial_state -> ni_get_ps(NULL) -> read NULL+0x28 -> page fault -> panic",
  "evidence": "run.log [A]: child died from SIGSEGV (signal 11): NULL+0x28 read; [B] fixed: rc=-EINVAL (DPM enable refused, no dereference); fix_build.log: si_dpm.o built rc=0 with -Werror",
  "kernel_refs": [
    "sys/dev/drm/radeon/si_dpm.c:6354",
    "sys/dev/drm/radeon/si_dpm.c:6401",
    "sys/dev/drm/radeon/si_dpm.c:4700",
    "sys/dev/drm/radeon/si_dpm.c:4746",
    "sys/dev/drm/radeon/si_dpm.c:4372",
    "sys/dev/drm/radeon/si_dpm.c:6726",
    "sys/dev/drm/radeon/ni_dpm.c:733",
    "sys/dev/drm/radeon/radeon_pm.c:1448",
    "sys/dev/drm/radeon/radeon_pm.c:1449"
  ],
  "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-3610 && sh build.sh",
  "run_cmd": "cd findings/poc/DF-3610 && sh run.sh",
  "code_hash": "828f870b6fa4dbdfb758c5b259ea6bfa28d638334dd2e4161ed4e18c2716e142",
  "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 (boot_ps == NULL) return -EINVAL;` at si_dpm_enable top. git apply --check OK; stacked with 4 other fixes the module TU compiles -Werror clean (si_dpm.o, 87080 B); harness [B] shows enable refused instead of faulting.)",
  "fix_evidence": "fix.diff adds `if (boot_ps == NULL) return -EINVAL;` at si_dpm_enable top. git apply --check OK; stacked with 4 other fixes the module TU compiles -Werror clean (si_dpm.o, 87080 B); harness [B] shows enable refused instead of faulting."
}