DF-4564 / verdict.json
{ "finding_id": "DF-4564", "status": "not_reproduced", "reproduced": 0, "impact": "dos", "confidence": "likely", "verdict": "DragonFlys port of radeon_driver_open_kms() dropped both upstream radeon_bo_unreserve(rdev->ring_tmp_bo.bo) calls (Linux v3.18 radeon_kms.c): the IB-pool BO reservation taken at radeon_kms.c:662 is never released on any path - the only unreserve in the whole driver is postcloses, guarded by its own blocking reserve at :733. radeon_bo_reserve(bo,false) is a non-interruptible ww_mutex_lock, so on any cayman+ radeon with accel_working the first client close() blocks forever in postclose and every subsequent open() by any user blocks forever at :662 - the DRM device is permanently wedged system-wide by an unprivileged open/close with no auth or ioctls. Runtime not verifiable on the audit guest (QEMU, no radeon GPU, /dev/dri absent), so the runtime manifestation is assessed from the ww_mutex semantics; the reservation leak itself is certain by construction and by upstream diff.", "exploit_chain": "unpriv user with /dev/dri/card0 access on cayman+ hw: open(); close() -> close hangs uninterruptibly in radeon_driver_postclose_kms (ww_mutex_lock) and the fd never finishes closing; every later open() by any process (X server, GL apps) blocks forever at the same reservation in radeon_driver_open_kms -> whole-system GPU DoS. Error-path variant (vm_bo_add ENOMEM / set_addr failure) wedges the device without any client surviving.", "evidence": "VERDICT.md (construction proof + upstream v3.18 excerpt + rg proof that the only unreserve is radeon_kms.c:737); README.md; fix.diff restoring the two upstream unreserve calls", "kernel_refs": [ "sys/dev/drm/radeon/radeon_kms.c:662-680", "sys/dev/drm/radeon/radeon_kms.c:689-692", "sys/dev/drm/radeon/radeon_kms.c:733-737", "sys/dev/drm/radeon/radeon_object.h:64-72", "sys/dev/drm/include/drm/ttm/ttm_bo_driver.h:653-676" ], "poc_changes": "No seed PoC; no trigger authored - the bug is a lock-lifetime defect requiring physical cayman+ radeon hardware to exercise; evidence is the code-trace divergence against Linux v3.18 drivers/gpu/drm/radeon/radeon_kms.c radeon_driver_open_kms.", "attempts": 0, "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul 2 06:02:54 UTC 2026 x86_64 (no radeon GPU; /dev/dri absent)", "runtime_sec": 0, "guest_dirty": 0, "build_cmd": null, "run_cmd": null, "code_hash": null, "notes": "not_reproduced solely because the guest has no radeon device; the defect is certain by construction: reserve at radeon_kms.c:662 with zero matching unreserve on any path reachable from open() (success or error). Upstream Linux v3.18 has the unreserve both in the !ib_bo_va error path and unconditionally after radeon_vm_bo_set_addr; the DF port dropped both. Clean pass-2 negatives for this file recorded in VERDICT.md (info ioctl copyout sizes match array declarations, gem_va/cs accel guards intact, vblank bounds checks correct, GEM_USERPTR compiled out).", "recommended_fix": "Restore the two upstream radeon_bo_unreserve(rdev->ring_tmp_bo.bo) calls in radeon_driver_open_kms() - error path after failed vm_bo_add, and unconditionally after radeon_vm_bo_set_addr (see fix.diff).", "fix_status": "not_testable", "fix_baseline_reproduced": 0, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff restores the upstream unreserve calls verbatim; not runtime-testable on this guest (no radeon GPU).", "fix_evidence": "fix.diff; upstream reference in VERDICT.md" } |