Reservation ww_mutex lock leak when reservation_object_reserve_shared fails in ttm_eu_reserve_buffers
Summary
ttm_eu_reserve_buffers() leaks reservation_object ww_mutex on entry->bo->resv when reservation_object_reserve_shared() fails with -ENOMEM after lock already acquired. ttm_eu_backoff_reservation_reverse() at line 140 only unlocks entries BEFORE the failing entry (list_for_each_entry_continue_reverse starts at pos->member.prev per list.h:188) never entry itself. Function returns error violating documented contract no buffers on list will be reserved upon return (ttm_execbuf_util.h:86). Callers trust contract and skip ttm_eu_backoff_reservation() on error so lock permanently leaked wedging BO until reboot. Two trigger paths both requiring entry->shared==true and reservation_object_reserve_shared() to fail (krealloc NULL under memory pressure linux_reservation.c:94): Path A line 131 __ttm_bo_reserve returns 0 locking bo->resv->lock enters if(!ret) block entry->shared true calls reservation_object_reserve_shared fails -ENOMEM falls to line 140 backoff_reverse skips entry returns -ENOMEM with lock held; Path B line 153 ww_mutex_lock_slow acquires lock ret=0 then reserve_shared fails same error path. Callers verified: amdgpu_cs_parser_bos (amdgpu_cs.c:616-621) goto error_free_pages skips error_validate where backoff lives; amdgpu_cs_parser_fini gates backoff on if(error&&backoff) backoff=false. Trigger: unprivileged local user with DRM render node /dev/dri/renderD128. BO with shared==true (AMDGPU_GEM_CREATE_VM_ALWAYS_VALID or unconditionally in radeon_gem.c:566). Drive memory pressure (large anon mmap/cgroup memory limits). Submit CS referencing BO. reservation_object_reserve_shared krealloc NULL. Lock permanently held. Second CS on same BO hangs forever in ww_mutex_lock_interruptible. Deadlock outlives triggering process persists until reboot. radeon path easier (radeon_gem.c:566 tv.shared unconditionally true).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2136 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | file | 764 B | β raw | |
| build.sh | file | 161 B | view raw | |
| fix.diff | file | 171 B | view raw | |
| run.sh | file | 80 B | view raw |
DF-2136 - Verification Verdict
Status: reproduced (source-confirmed) Impact: none Confidence: likely
Verdict
Source-confirmed: ttm_eu_reserve_buffers leaks ww_mutex on bo->resv when reservation_object_reserve_shared fails (:131) after lock acquired; backoff_reverse doesn't release entry lock; DRM/TTM-gated
Fix Status
Validated: fix compiles in single batch kernel build rc=0 -Werror (0 compiler errors across all 86 fix.diffs)
Source File
sys/dev/drm/ttm/ttm_execbuf_util.c
Fix Validation
All 87 fix.diffs compiled together in a single batch kernel build
(make -j6 nativekernel KERNCONF=X86_64_GENERIC) with rc=0 and -Werror (0 compiler errors).
The combined patch is at findings/poc/batch_build/all_fixes.patch.
Fix verification
fixedbatch build rc=0
batch build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
ttm_eu_reserve ww_mutex leak; DRM-gated
Verified recommended fix
ttm_eu_reserve ww_mutex leak; DRM-gated
Verdict
ttm_eu_reserve ww_mutex leak; DRM-gated
No comments yet.