Skip to contentSkip to conversation

dmaengine: dw-edma: Fix use after free in dw_edma_alloc_chunk()

PATCH Applied Dan Carpenter 3 participants 3 messages Dec 14, 2020 – Dec 21, 2020

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 dmaengine: dw-edma: Fix use after free in dw_edma_alloc_chunk()

If the dw_edma_alloc_burst() function fails then we free "chunk" but it's still on the "desc->chunk->list" list so it will lead to a use after free. Also the "->chunks_alloc" count is incremented when it shouldn't be.

In current kernels small allocations are guaranteed to succeed and dw_edma_alloc_burst() can't fail so this will not actually affect runtime.

Fixes e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver")

---
Based on static analysis. Not tested.

 drivers/dma/dw-edma/dw-edma-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/dma/dw-edma/dw-edma-core.c +2 -2
index b971505b8715..08d71dafa001 100644
@@ -86,12 +86,12 @@ static struct dw_edma_chunk *dw_edma_alloc_chunk(struct dw_edma_desc *desc)
 
 	if (desc->chunk) {
 		/* Create and add new element into the linked list */
-		desc->chunks_alloc++;
-		list_add_tail(&chunk->list, &desc->chunk->list);
 		if (!dw_edma_alloc_burst(chunk)) {
 			kfree(chunk);
 			return NULL;
 		}
+		desc->chunks_alloc++;
+		list_add_tail(&chunk->list, &desc->chunk->list);
 	} else {
 		/* List head */
 		chunk->burst = NULL;
Signature · 1 line
2.29.2
Acked-by on v1 1/1
#1 lore raw
Quoted 38 lines · Dan Carpenter

If the dw_edma_alloc_burst() function fails then we free "chunk" but it's still on the "desc->chunk->list" list so it will lead to a use after free. Also the "->chunks_alloc" count is incremented when it shouldn't be.

In current kernels small allocations are guaranteed to succeed and dw_edma_alloc_burst() can't fail so this will not actually affect runtime.

Fixes e63d79d1ffcd ("dmaengine: Add Synopsys eDMA IP core driver")

---
Based on static analysis. Not tested.

 drivers/dma/dw-edma/dw-edma-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/dma/dw-edma/dw-edma-core.c +2 -2
index b971505b8715..08d71dafa001 100644
@@ -86,12 +86,12 @@ static struct dw_edma_chunk *dw_edma_alloc_chunk(struct dw_edma_desc *desc)
 
 	if (desc->chunk) {
 		/* Create and add new element into the linked list */
-		desc->chunks_alloc++;
-		list_add_tail(&chunk->list, &desc->chunk->list);
 		if (!dw_edma_alloc_burst(chunk)) {
 			kfree(chunk);
 			return NULL;
 		}
+		desc->chunks_alloc++;
+		list_add_tail(&chunk->list, &desc->chunk->list);
 	} else {
 		/* List head */
 		chunk->burst = NULL;
Signature · 1 line
2.29.2

Thanks for the fix! Nicely catch!

maintainer Applied
#2 lore raw
In reply to Dan Carpenter
Quoted 8 lines · Dan Carpenter

If the dw_edma_alloc_burst() function fails then we free "chunk" but it's still on the "desc->chunk->list" list so it will lead to a use after free. Also the "->chunks_alloc" count is incremented when it shouldn't be.

In current kernels small allocations are guaranteed to succeed and dw_edma_alloc_burst() can't fail so this will not actually affect runtime.

Applied, thanks

Signature · 1 line
~Vinod