⬢ DragonFlyBSD Kernel Audit
DF-4162 / verdict.json
← back to finding ↓ download raw
{
  "finding_id": "DF-4162",
  "status": "inconclusive",
  "reproduced": 0,
  "impact": "none",
  "confidence": "certain",
  "verdict": "Source-level certain, runtime hardware-gated (inconclusive per family convention). radeon_pm_init_dpm calls the asic init as a void statement -- radeon_dpm_init(rdev); at radeon_pm.c:1448, macro radeon.h:2793 expands to rdev->asic->dpm.init((rdev)) returning int -- discarding the error upstream honors (ret = radeon_dpm_init(rdev); if (ret) goto dpm_failed;). Verified failure semantics: (a) parse errors return -EINVAL/-ENOMEM (swallowed here); (b) a VBIOS table with no BOOT-classified state returns 0 with boot_ps NULL because boot_ps is only assigned inside the per-state loops (rv770_dpm.c:2172, rv6xx_dpm.c:1811, trinity_dpm.c:1705, si_dpm.c:6727) and NO dispatch init validates it. With the error dropped, :1449 publishes current_ps=requested_ps=boot_ps (NULL/dangling), :1452-1453 run setup_asic+enable whose per-asic bodies deref boot_ps (rv770_dpm.c:1901, rv6xx_dpm.c:1577, btc/trinity/cypress twins = DF-4022/4118/4124/4143/3972 attach panics); the dangling ps survives into radeon_dpm_fini at unload (DF-4117/4125/4144 double frees); suspend/resume/fini-disable re-deref boot_ps (:1262/:1320/:1694) because pm_method stays PM_METHOD_DPM -- the second swallow layer being the asic *_init files calling radeon_pm_init(rdev); as a statement (si.c:6874, ni.c:2432, cik.c:8653, evergreen.c:5235, rv770.c:1962, r600.c:3321). Central fix (fix.diff, one file, covers all six dispatch files): honor the return; explicit if (!rdev->pm.dpm.boot_ps) goto dpm_init_failed gate (closes case (b) which the return alone does not -- rv7xx_parse_power_table returns 0 with boot_ps unset, rv770_dpm.c:2271-2329); scrub ps/boot_ps/current_ps/num_ps on init failure so dpm_fini cannot double-free; gate suspend_dpm/resume_dpm/finis radeon_dpm_disable on boot_ps. Assessment: applying it makes the six family enable-side NULL-boot_ps panics unreachable at boot AND at suspend/resume/unload-disable, and neutralizes the ps double-frees; residual per-asic ext-table double-frees still need the already-filed dispatch fixes. Guest: virtio VGA only, zero 0x1002 devices, hw.drm unknown (env.txt) -> not runtime-testable.",
  "exploit_chain": "On radeon hardware: crafted/reflash VBIOS PowerPlayInfo without BOOT state (passthrough/hotplug) -> drm attach panics (family signature) or unload double-free. No write primitive controlled by the attacker; primarily reboot-loop DoS plus allocator poisoning window on the double free.",
  "evidence": "VERDICT.md (two-layer swallow proof + fix-coverage assessment, path:line); env.txt (hardware absence + md5 962543e6e0739668ac24e0b255a44b61 == audited tree); fix.diff (central hub fix, git apply --check clean, 76 lines)",
  "kernel_refs": [
    "sys/dev/drm/radeon/radeon_pm.c:1448",
    "sys/dev/drm/radeon/radeon_pm.c:1449",
    "sys/dev/drm/radeon/radeon_pm.c:1453",
    "sys/dev/drm/radeon/radeon_pm.c:1262",
    "sys/dev/drm/radeon/radeon_pm.c:1320",
    "sys/dev/drm/radeon/radeon_pm.c:1694",
    "sys/dev/drm/radeon/radeon.h:2793",
    "sys/dev/drm/radeon/si.c:6874",
    "sys/dev/drm/radeon/rv770_dpm.c:2172",
    "sys/dev/drm/radeon/rv770_dpm.c:2271",
    "sys/dev/drm/radeon/rv770_dpm.c:1901"
  ],
  "poc_changes": "No seed PoC. Trigger is the DF-4022 family VBIOS trigger; this pack contributes the central fix.diff instead.",
  "attempts": 1,
  "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": 15,
  "guest_dirty": 0,
  "build_cmd": "n/a (hardware-gated)",
  "run_cmd": "n/a (hardware-gated; VBIOS trigger per DF-4022)",
  "code_hash": "",
  "notes": "The orchestrator-requested systemic consolidation of DF-4022/4117/4118/4124/4125/4143/4144 (+DF-3972). Verified this pass: no dispatch init checks boot_ps (grep clean); rv7xx_parse_power_table returns 0 without BOOT state; asic fini order keeps IRQs live after pm_fini (si.c:6945 vs 6950) which is DF-4163s adjacent-but-separate defect; radeon_pm_print_states name array [5] only indexed by legacy types 0..4 (enum radeon.h:1206-1225).",
  "recommended_fix": "Honor radeon_dpm_inits return, gate on boot_ps, scrub dangling ps, and guard suspend/resume/fini-disable paths in radeon_pm.c (see fix.diff).",
  "fix_status": "not_testable",
  "fix_baseline_reproduced": 0,
  "fix_patched_reproduced": 0,
  "fix_verdict": "fix.diff applies clean (git apply --check) against the read-only tree; single-file central fix that makes the six family boot/suspend/resume NULL-boot_ps panics unreachable and neutralizes the ps double-frees; cannot be runtime-validated without radeon hardware.",
  "fix_evidence": "findings/poc/DF-4162/fix.diff"
}