dma-buf/dma-resv: Stop leaking on krealloc() failure
authorjsg <jsg@openbsd.org>
Fri, 28 Jul 2023 06:30:13 +0000 (06:30 +0000)
committerjsg <jsg@openbsd.org>
Fri, 28 Jul 2023 06:30:13 +0000 (06:30 +0000)
From Ville Syrjala
19e7b9f1f7e1cb92a4cc53b4c064f7fb4b1f1983 in linux-6.1.y/6.1.42
05abb3be91d8788328231ee02973ab3d47f5e3d2 in mainline linux

sys/dev/pci/drm/dma-resv.c

index 76da6c7..8461b4d 100644 (file)
@@ -572,6 +572,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)
@@ -581,9 +582,9 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
 
                        /* Eventually re-allocate the array */
 #ifdef __linux__
-                       *fences = krealloc_array(*fences, count,
-                                                sizeof(void *),
-                                                GFP_KERNEL);
+                       new_fences = krealloc_array(*fences, count,
+                                                   sizeof(void *),
+                                                   GFP_KERNEL);
 #else
                        nfences = kmalloc(count * sizeof(void *),
                                                 GFP_KERNEL);
@@ -592,13 +593,17 @@ int dma_resv_get_fences(struct dma_resv *obj, enum dma_resv_usage usage,
                                    (count - 1) *  sizeof(void *));
                        if (nfences) {
                                kfree(*fences);
-                               *fences = nfences;
+                               new_fences = nfences;
                        }
 #endif
-                       if (count && !*fences) {
+                       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);