⬢ DragonFlyBSD Kernel Audit
DF-4564 / verdict.json
← back to finding ↓ download raw
{
  "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"
}