{
  "finding_id": "DF-5230",
  "status": "reproduced",
  "verdict": "uvd_v4_2_resume() dereferences rdev->uvd_fw->datasize at sys/dev/drm/radeon/uvd_v4_2.c:51 with no guard. The cik_uvd_start() caller is guarded (has_uvd, cik.c:8167; vcpu_bo, radeon_uvd.c:286), but the KV DPM ungate caller is not: any suspend or pm-fini on a DPM-enabled KV/CIK APU (KAVERI/KABINI/MULLINS) whose UVD firmware kmods are absent (uvd_fw NULL after failed radeon_uvd_init, radeon_uvd.c:137/176; has_uvd cleared cik.c:8156 while DPM stays up from SMC fw) reaches kv_dpm.c:1628 via cik.c:8545 -> radeon_pm.c:1257 -> radeon.h:2797 -> kv_dpm.c:1305,1316,1608 (caps_uvd_pg always true kv_dpm.c:2773; uvd_power_gated set true at boot kv_dpm.c:1300) and panics. The guest has no AMD GPU, so verification used a harness kld that reconstructs the exact post-failed-init radeon_device state (uvd_fw=NULL, fw_header_present=false, gpu_addr=0, max_handles=10) and calls the PRODUCTION uvd_v4_2_resume compiled into a freshly built radeon.ko: deterministic panic fault virtual address = 0x10 (offsetof(struct firmware, datasize)) at uvd_v4_2_resume+0x30: movq 0x10(%rdx),%rdx, reproduced twice, the second from a fresh vm.sh reset with reverted source; fault precedes the first WREG32 so no MMIO is touched. With fix.diff (one-line uvd_fw==NULL -> -EINVAL guard) applied in the guest /usr/src and radeon.ko rebuilt, the identical trigger prints survived, uvd_v4_2_resume returned -22 and the guest stays up. Field trigger is hardware-gated (KV APU + SMC-without-UVD fw config); impact ceiling is a local DoS panic (pure data read, no write primitive).",
  "reproduced": true,
  "impact": "panic",
  "confidence": "certain",
  "exploit_chain": "",
  "evidence": "panic.txt + panic.2.txt (serial console: DF5230 markers, Fatal trap 12, fault VA 0x10, Stopped at uvd_v4_2_resume+0x30 movq 0x10(%rdx),%rdx -- twice, second from fresh reset); run.fixed.log / fix_run.log (patched radeon.ko: survived, uvd_v4_2_resume returned -22, guest up); VERDICT.md (full link-by-link production trigger chain with path:line); fix.diff (git apply --check clean); env.txt (no AMD PCI device on guest)",
  "kernel_refs": [
    "sys/dev/drm/radeon/uvd_v4_2.c:51",
    "sys/dev/drm/radeon/kv_dpm.c:1628",
    "sys/dev/drm/radeon/kv_dpm.c:1608",
    "sys/dev/drm/radeon/kv_dpm.c:1305",
    "sys/dev/drm/radeon/kv_dpm.c:1300",
    "sys/dev/drm/radeon/kv_dpm.c:2773",
    "sys/dev/drm/radeon/radeon_pm.c:1257",
    "sys/dev/drm/radeon/radeon_pm.c:1694",
    "sys/dev/drm/radeon/radeon.h:2797",
    "sys/dev/drm/radeon/cik.c:8545",
    "sys/dev/drm/radeon/cik.c:8167",
    "sys/dev/drm/radeon/radeon_uvd.c:137",
    "sys/dev/drm/radeon/radeon_uvd.c:286",
    "sys/dev/drm/radeon/radeon_asic.c:2285",
    "sys/sys/firmware.h:51"
  ],
  "poc_changes": "no seed; harness written fresh (df5230.c: zeroed struct radeon_device + max_handles=10 == post-failed-radeon_uvd_init state, calls production radeon.ko symbol; MODULE_DEPEND removed because radeon.ko declares no MODULE_VERSION so a versioned dep always fails)",
  "attempts": 3,
  "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": 12,
  "guest_dirty": 0,
  "build_cmd": "cd /usr/src/sys/dev/drm/drm && make -j6 && cd ../radeon && make -j6 && cd /root/df5230 && make",
  "run_cmd": "kldload /usr/src/sys/dev/drm/drm/drm.ko && kldload /usr/src/sys/dev/drm/radeon/radeon.ko && kldload /root/df5230/df5230.ko",
  "code_hash": "ed116247c35bd29e2307005c8c35806438d8024c02f8478ca86c786f86cd0662",
  "notes": "synthetic-state harness calling the production function (no KV APU on guest); production chain proven statically path:line; fault is a data read -> DoS ceiling only; guest reset clean (vm.sh reset with-src) after validation; trigger context: DragonFly ships all radeon fw as separate opt-in radeonkmsfw_* kmods, so SMC-loaded-without-UVD is a natural config, not contrived",
  "recommended_fix": "one-line guard in uvd_v4_2_resume: if (rdev->uvd_fw == NULL) return -EINVAL; (mirrors has_uvd/vcpu_bo guards of the other paths)",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Baseline (stock radeon.ko): identical trigger panics (fault VA 0x10 at uvd_v4_2_resume+0x30), twice, second from a fresh vm.sh reset with reverted source. Patched (fix.diff in guest /usr/src, radeon.ko rebuilt): identical trigger returns -22, prints survived, guest stays up, kldload succeeds. The previously-observed panic is GONE under the fix.",
  "fix_evidence": "fix_run.log (patched-kernel run: survived/returned -22, guest up); fix_build.log (patch + incremental rebuild transcript); panic.txt/panic.2.txt (baseline); fix.diff"
}