Commit 92cb3e59 authored by Christian König's avatar Christian König
Browse files

dma-buf: fix stack corruption in dma_fence_chain_release



We can't free up the chain using recursion or we run into a stack overflow.

Manually free up the dangling chain nodes to avoid recursion.

Signed-off-by: default avatarChristian König <christian.koenig@amd.com>
Acked-by: default avatarLionel Landwerlin <lionel.g.landwerlin@intel.com>
Fixes: 7bf60c52 ("dma-buf: add new dma_fence_chain container v7")
Link: https://patchwork.freedesktop.org/patch/321612/
parent 0dbd555a
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -178,8 +178,30 @@ static bool dma_fence_chain_signaled(struct dma_fence *fence)
static void dma_fence_chain_release(struct dma_fence *fence)
{
	struct dma_fence_chain *chain = to_dma_fence_chain(fence);
	struct dma_fence *prev;

	/* Manually unlink the chain as much as possible to avoid recursion
	 * and potential stack overflow.
	 */
	while ((prev = rcu_dereference_protected(chain->prev, true))) {
		struct dma_fence_chain *prev_chain;

		if (kref_read(&prev->refcount) > 1)
		       break;

		prev_chain = to_dma_fence_chain(prev);
		if (!prev_chain)
			break;

		/* No need for atomic operations since we hold the last
		 * reference to prev_chain.
		 */
		chain->prev = prev_chain->prev;
		RCU_INIT_POINTER(prev_chain->prev, NULL);
		dma_fence_put(prev);
	}
	dma_fence_put(prev);

	dma_fence_put(rcu_dereference_protected(chain->prev, true));
	dma_fence_put(chain->fence);
	dma_fence_free(fence);
}