{
  "finding_id": "DF-3645",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-certain lifetime bug, radeon/ci twin of DF-3588 (amdgpu), DF-3611 (radeon si), DF-3624 (amdgpu ci). Three legs: (1) ci_parse_power_tables error path (ci_dpm.c:5669-5673) kfrees rdev->pm.dpm.ps and every ps_priv but leaves rdev->pm.dpm.ps dangling and num_ps at its parsed value. The path is reachable when the per-state kzalloc fails (5624-5628) or when the rdev->pm.power_state[i].clock_info guard (5620-5623) trips - which it does whenever radeon_atombios_parse_power_table_4_5 bailed out early leaving later entries NULL, and the guard itself reads rdev->pm.power_state[i] out of bounds when the legacy parser fell back to its single default power_state (radeon_atombios.c:2784) while ci iterates the crafted state_array->ucNumEntries. (2) ci_dpm_init error paths (5764/5770/5776/5782) kfree rdev->pm.dpm.priv without NULLing it. (3) radeon_pm_init_dpm (radeon_pm.c:1448) calls radeon_dpm_init(rdev) and DISCARDS the return, then immediately runs radeon_dpm_setup_asic() -> ci_dpm_setup_asic -> ci_read_clock_registers (ci_dpm.c:1904-1929), which WRITES 14 register values into the freed ci_power_info, and radeon_dpm_enable -> ci_dpm_enable which reads pi->voltage_control from freed memory. At teardown, radeon_driver_unload_kms -> radeon_device_fini -> cik_fini (cik.c:8730) -> radeon_pm_fini -> radeon_pm_fini_dpm -> ci_dpm_fini (ci_dpm.c:5703-5714) unconditionally kfrees the already-freed ps_priv array, ps array and priv -> double free. Kernel-level reproduction is impossible on this virtio-only guest; verdict inconclusive with source-level certainty.",
  "exploit_chain": "Force a ci_dpm_init failure with rdev->pm.dpm state already populated (memory-pressure kzalloc failure inside ci_parse_power_table, or a crafted VBIOS whose legacy power-state parse leaves power_state[i].clock_info NULL for some i < ucNumEntries): boot then writes into freed ci_power_info (UAF write of hardware register values) and unloading the driver double-frees the ps array - classic exploitable double-free on the DRM slab if the intervening UAF writes havent already crashed. Requires the same crafted-VBIOS/allocation-pressure preconditions as the si twin DF-3611; no CI hardware on this guest so no kernel-path PoC was possible.",
  "evidence": "VERDICT.md (full source trace); env.txt (guest has no AMD GPU: pciconf 0x1002 count=0, /dev/dri absent, no drm kld); fix.diff",
  "kernel_refs": [
    "sys/dev/drm/radeon/ci_dpm.c:5608",
    "sys/dev/drm/radeon/ci_dpm.c:5620",
    "sys/dev/drm/radeon/ci_dpm.c:5624",
    "sys/dev/drm/radeon/ci_dpm.c:5669",
    "sys/dev/drm/radeon/ci_dpm.c:5703",
    "sys/dev/drm/radeon/ci_dpm.c:5764",
    "sys/dev/drm/radeon/ci_dpm.c:5782",
    "sys/dev/drm/radeon/ci_dpm.c:5835",
    "sys/dev/drm/radeon/radeon_pm.c:1448",
    "sys/dev/drm/radeon/radeon_pm.c:1458",
    "sys/dev/drm/radeon/ci_dpm.c:1904",
    "sys/dev/drm/radeon/cik.c:8730",
    "sys/dev/drm/radeon/radeon_atombios.c:2784"
  ],
  "poc_changes": "n/a \u2014 no seeded PoC; source-trace only",
  "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": 45,
  "guest_dirty": 0,
  "build_cmd": null,
  "run_cmd": null,
  "code_hash": null,
  "notes": "pass 2 radeon/ci_dpm.c; twins: DF-3588/DF-3611/DF-3624. Guest virtio-only per task; harness scratch files under /root removed.",
  "recommended_fix": "NULL out rdev->pm.dpm.{ps,priv} and reset num_ps on every free site in ci_dpm.c, and honor the radeon_dpm_init() return value in radeon_pm_init_dpm().",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Fix validation would require a CI-class GPU with a crafted VBIOS (baseline panic/corruption) and a single-fix kernel build; the audit guest is virtio-only, so the fix is source-reviewed only (fix.diff).",
  "fix_evidence": "fix.diff in this pack; not applied to sys/ (read-only audit target)."
}