DF-3610 / verdict.json
{ "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." } |