This is a note to let you know that I've just added the patch titled dma-buf/sync_file: Don't leak fences on merge failure to the 5.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: dma-buf-sync_file-don-t-leak-fences-on-merge-failure.patch and it can be found in the queue-5.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From ffe000217c5068c5da07ccb1c0f8cce7ad767435 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand <jason@xxxxxxxxxxxxxx> Date: Thu, 24 Jun 2021 12:47:32 -0500 Subject: dma-buf/sync_file: Don't leak fences on merge failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Jason Ekstrand <jason@xxxxxxxxxxxxxx> commit ffe000217c5068c5da07ccb1c0f8cce7ad767435 upstream. Each add_fence() call does a dma_fence_get() on the relevant fence. In the error path, we weren't calling dma_fence_put() so all those fences got leaked. Also, in the krealloc_array failure case, we weren't freeing the fences array. Instead, ensure that i and fences are always zero-initialized and dma_fence_put() all the fences and kfree(fences) on every error path. Signed-off-by: Jason Ekstrand <jason@xxxxxxxxxxxxxx> Reviewed-by: Christian König <christian.koenig@xxxxxxx> Fixes: a02b9dc90d84 ("dma-buf/sync_file: refactor fence storage in struct sync_file") Cc: Gustavo Padovan <gustavo.padovan@xxxxxxxxxxxxxxx> Cc: Christian König <christian.koenig@xxxxxxx> Link: https://patchwork.freedesktop.org/patch/msgid/20210624174732.1754546-1-jason@xxxxxxxxxxxxxx Signed-off-by: Christian König <christian.koenig@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/dma-buf/sync_file.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -211,8 +211,8 @@ static struct sync_file *sync_file_merge struct sync_file *b) { struct sync_file *sync_file; - struct dma_fence **fences, **nfences, **a_fences, **b_fences; - int i, i_a, i_b, num_fences, a_num_fences, b_num_fences; + struct dma_fence **fences = NULL, **nfences, **a_fences, **b_fences; + int i = 0, i_a, i_b, num_fences, a_num_fences, b_num_fences; sync_file = sync_file_alloc(); if (!sync_file) @@ -236,7 +236,7 @@ static struct sync_file *sync_file_merge * If a sync_file can only be created with sync_file_merge * and sync_file_create, this is a reasonable assumption. */ - for (i = i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) { + for (i_a = i_b = 0; i_a < a_num_fences && i_b < b_num_fences; ) { struct dma_fence *pt_a = a_fences[i_a]; struct dma_fence *pt_b = b_fences[i_b]; @@ -278,15 +278,16 @@ static struct sync_file *sync_file_merge fences = nfences; } - if (sync_file_set_fence(sync_file, fences, i) < 0) { - kfree(fences); + if (sync_file_set_fence(sync_file, fences, i) < 0) goto err; - } strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); return sync_file; err: + while (i) + dma_fence_put(fences[--i]); + kfree(fences); fput(sync_file->file); return NULL; Patches currently in stable-queue which might be from jason@xxxxxxxxxxxxxx are queue-5.4/dma-buf-sync_file-don-t-leak-fences-on-merge-failure.patch