{
  "finding_id": "DF-3955",
  "title": "Double free of rdev->pm.dpm.ps (and leak of parsed ps_priv states) on the kzalloc-failure path of kv_parse_power_table (radeon kv_dpm)",
  "file": "sys/dev/drm/radeon/kv_dpm.c",
  "severity": "Low",
  "status": "inconclusive",
  "impact_class": "heap corruption (double free), OOM-gated",
  "verdict": {
    "reproduced": false,
    "confidence": "likely (source-certain path; the kzalloc failure itself is memory-pressure-gated)",
    "summary": "kv_parse_power_table :2673-2677 frees rdev->pm.dpm.ps without NULLing it and with num_ps still 0; kv_dpm_fini :2861-2871 later kfree's it again (double free) while the already-parsed ps_priv objects leak (num_ps==0).",
    "harness_result": "sequence replay with injected OOM at state #2: dangling dpm_ps + leaked ps_priv count = 2 printed; free/free-again completes SILENTLY on DFly libc (kernel heap likewise does not detect double frees)"
  },
  "kernel_refs": [
    "sys/dev/drm/radeon/kv_dpm.c:2675",
    "sys/dev/drm/radeon/kv_dpm.c:2700",
    "sys/dev/drm/radeon/kv_dpm.c:2861",
    "sys/dev/drm/radeon/kv_dpm.c:2868",
    "sys/dev/drm/radeon/radeon_pm.c:1448"
  ],
  "reproduce": {
    "build": "cd findings/poc/DF-3955 && ./build.sh",
    "run": "cd findings/poc/DF-3955 && ./run.sh",
    "expected": "analysis: 'dangling dpm_ps = 0x... ; leaked ps_priv count = 2 ; num_ps = 0', exit 0 before second free; crash: 'SECOND FREE COMPLETED SILENTLY (userland no-abort; kernel: silent heap corruption)', exit 0"
  },
  "artifacts": [
    "README.md", "VERDICT.md", "trigger_df3955.c", "build.sh", "run.sh",
    "build.log", "run.log", "env.txt", "fix.diff", "manifest.json", "verdict.json"
  ]
}
