Skip to content

Commit 05abb3b

Browse files
vsyrjalaChristianKoenigAMD
authored andcommitted
dma-buf/dma-resv: Stop leaking on krealloc() failure
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]>
1 parent 73274c3 commit 05abb3b

File tree

1 file changed

+9
-4
lines changed

1 file changed

+9
-4
lines changed

drivers/dma-buf/dma-resv.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,7 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
571571
dma_resv_for_each_fence_unlocked(&cursor, fence) {
572572

573573
if (dma_resv_iter_is_restarted(&cursor)) {
574+
struct dma_fence **new_fences;
574575
unsigned int count;
575576

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

581582
/* Eventually re-allocate the array */
582-
*fences = krealloc_array(*fences, count,
583-
sizeof(void *),
584-
GFP_KERNEL);
585-
if (count && !*fences) {
583+
new_fences = krealloc_array(*fences, count,
584+
sizeof(void *),
585+
GFP_KERNEL);
586+
if (count && !new_fences) {
587+
kfree(*fences);
588+
*fences = NULL;
589+
*num_fences = 0;
586590
dma_resv_iter_end(&cursor);
587591
return -ENOMEM;
588592
}
593+
*fences = new_fences;
589594
}
590595

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

0 commit comments

Comments
 (0)