Skip to content

Commit

Permalink
dma-buf/dma-resv: Stop leaking on krealloc() failure
Browse files Browse the repository at this point in the history
Currently dma_resv_get_fences() will leak the previously
allocated array if the fence iteration got restarted and
the krealloc_array() fails.

Free the old array by hand, and make sure we still clear
the returned *fences so the caller won't end up accessing
freed memory. Some (but not all) of the callers of
dma_resv_get_fences() seem to still trawl through the
array even when dma_resv_get_fences() failed. And let's
zero out *num_fences as well for good measure.

Cc: Sumit Semwal <[email protected]>
Cc: Christian König <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: [email protected]
Fixes: d3c8069 ("dma-buf: use new iterator in dma_resv_get_fences v3")
Signed-off-by: Ville Syrjälä <[email protected]>
Reviewed-by: Christian König <[email protected]>
Cc: [email protected]
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Signed-off-by: Christian König <[email protected]>
  • Loading branch information
vsyrjala authored and ChristianKoenigAMD committed Jul 15, 2023
1 parent 73274c3 commit 05abb3b
Showing 1 changed file with 9 additions and 4 deletions.
13 changes: 9 additions & 4 deletions drivers/dma-buf/dma-resv.c
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
dma_resv_for_each_fence_unlocked(&cursor, fence) {

if (dma_resv_iter_is_restarted(&cursor)) {
struct dma_fence **new_fences;
unsigned int count;

while (*num_fences)
Expand All @@ -579,13 +580,17 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
count = cursor.num_fences + 1;

/* Eventually re-allocate the array */
*fences = krealloc_array(*fences, count,
sizeof(void *),
GFP_KERNEL);
if (count && !*fences) {
new_fences = krealloc_array(*fences, count,
sizeof(void *),
GFP_KERNEL);
if (count && !new_fences) {
kfree(*fences);
*fences = NULL;
*num_fences = 0;
dma_resv_iter_end(&cursor);
return -ENOMEM;
}
*fences = new_fences;
}

(*fences)[(*num_fences)++] = dma_fence_get(fence);
Expand Down

0 comments on commit 05abb3b

Please sign in to comment.