提交 15ee9498 编写于 作者: J Jason Ekstrand 提交者: Yang Yingliang

dma-buf/sync_file: Don't leak fences on merge failure

stable inclusion
from linux-4.19.199
commit e0355a0ad31a1d677b2a4514206de4902bd550e8

--------------------------------

commit ffe00021 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: NJason Ekstrand <jason@jlekstrand.net>
Reviewed-by: NChristian König <christian.koenig@amd.com>
Fixes: a02b9dc9 ("dma-buf/sync_file: refactor fence storage in struct sync_file")
Cc: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Cc: Christian König <christian.koenig@amd.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210624174732.1754546-1-jason@jlekstrand.netSigned-off-by: NChristian König <christian.koenig@amd.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 187f901d
...@@ -220,8 +220,8 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, ...@@ -220,8 +220,8 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
struct sync_file *b) struct sync_file *b)
{ {
struct sync_file *sync_file; struct sync_file *sync_file;
struct dma_fence **fences, **nfences, **a_fences, **b_fences; struct dma_fence **fences = NULL, **nfences, **a_fences, **b_fences;
int i, i_a, i_b, num_fences, a_num_fences, b_num_fences; int i = 0, i_a, i_b, num_fences, a_num_fences, b_num_fences;
sync_file = sync_file_alloc(); sync_file = sync_file_alloc();
if (!sync_file) if (!sync_file)
...@@ -245,7 +245,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, ...@@ -245,7 +245,7 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
* If a sync_file can only be created with sync_file_merge * If a sync_file can only be created with sync_file_merge
* and sync_file_create, this is a reasonable assumption. * 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_a = a_fences[i_a];
struct dma_fence *pt_b = b_fences[i_b]; struct dma_fence *pt_b = b_fences[i_b];
...@@ -286,15 +286,16 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a, ...@@ -286,15 +286,16 @@ static struct sync_file *sync_file_merge(const char *name, struct sync_file *a,
fences = nfences; fences = nfences;
} }
if (sync_file_set_fence(sync_file, fences, i) < 0) { if (sync_file_set_fence(sync_file, fences, i) < 0)
kfree(fences);
goto err; goto err;
}
strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name)); strlcpy(sync_file->user_name, name, sizeof(sync_file->user_name));
return sync_file; return sync_file;
err: err:
while (i)
dma_fence_put(fences[--i]);
kfree(fences);
fput(sync_file->file); fput(sync_file->file);
return NULL; return NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册