Commit 7a14a4e9 authored by Sunil Khatri's avatar Sunil Khatri Committed by Alex Deucher
Browse files

drm/amdgpu/userq: fix dma_fence refcount underflow in userq path



An extra dma_fence_put() can drop the last reference to a fence while it is
still attached to a dma_resv object. This frees the fence prematurely via
dma_fence_release() while other users still hold the pointer.

Later accesses through dma_resv iteration may then operate on the freed
fence object, leading to refcount underflow warnings and potential hangs
when walking reservation fences.

Fix this by correcting the fence lifetime so the dma_resv object retains a
valid reference until it is done with the fence.i

[   31.133803] refcount_t: underflow; use-after-free.
[   31.133805] WARNING: lib/refcount.c:28 at refcount_warn_saturate+0x58/0x90, CPU#18: kworker/u96:1/188

Signed-off-by: default avatarSunil Khatri <sunil.khatri@amd.com>
Reviewed-by: default avatarTvrtko Ursulin <tvrtko.ursulin@igalia.com>
Reviewed-by: default avatarChristian König <christian.koenig@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 311f8fc0
Loading
Loading
Loading
Loading
+1 −5
Original line number Diff line number Diff line
@@ -881,12 +881,9 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
				 * be good for now
				 */
				r = dma_fence_wait(fences[i], true);
				if (r) {
					dma_fence_put(fences[i]);
				if (r)
					goto free_fences;
				}

				dma_fence_put(fences[i]);
				continue;
			}

@@ -908,7 +905,6 @@ int amdgpu_userq_wait_ioctl(struct drm_device *dev, void *data,
			fence_info[cnt].va = fence_drv->va;
			fence_info[cnt].value = fences[i]->seqno;

			dma_fence_put(fences[i]);
			/* Increment the actual userq fence count */
			cnt++;
		}