Skip to content

Commit c33efdf

Browse files
shankerd04mszyprow
authored andcommitted
dma: contiguous: Check return value of dma_contiguous_reserve_area()
Commit 8f1fc1b ("dma: contiguous: Reserve default CMA heap") introduced a bug where dma_heap_cma_register_heap() is called with a NULL pointer when dma_contiguous_reserve_area() fails to reserve the CMA area. When dma_contiguous_reserve_area() fails, dma_contiguous_default_area remains NULL (initialized as a global variable), but the code doesn't check the return value and proceeds to call dma_heap_cma_register_heap() with this NULL pointer. Later during boot, add_cma_heaps() iterates through the dma_areas[] array and attempts to register heaps. When it encounters the NULL pointer stored by the earlier call, it crashes in __add_cma_heap() -> dma_heap_add() when trying to dereference the NULL CMA pointer. The crash manifests as: Unable to handle kernel NULL pointer dereference at virtual address 0000000000000038 ... Call trace: dma_heap_add+0x40/0x2b0 __add_cma_heap+0x80/0xe0 add_cma_heaps+0x64/0xb0 do_one_initcall+0x60/0x318 kernel_init_freeable+0x260/0x2f0 kernel_init+0x2c/0x168 ret_from_fork+0x10/0x20 Fix this by checking the return value of dma_contiguous_reserve_area() and only calling dma_heap_cma_register_heap() when the reservation succeeds. Fixes: 8f1fc1b ("dma: contiguous: Reserve default CMA heap") Signed-off-by: Shanker Donthineni <[email protected]> Reviewed-by: T.J. Mercier <[email protected]> Signed-off-by: Marek Szyprowski <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent daafcc0 commit c33efdf

1 file changed

Lines changed: 6 additions & 4 deletions

File tree

kernel/dma/contiguous.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,12 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
257257
pr_debug("%s: reserving %ld MiB for global area\n", __func__,
258258
(unsigned long)selected_size / SZ_1M);
259259

260-
dma_contiguous_reserve_area(selected_size, selected_base,
261-
selected_limit,
262-
&dma_contiguous_default_area,
263-
fixed);
260+
ret = dma_contiguous_reserve_area(selected_size, selected_base,
261+
selected_limit,
262+
&dma_contiguous_default_area,
263+
fixed);
264+
if (ret)
265+
return;
264266

265267
ret = dma_heap_cma_register_heap(dma_contiguous_default_area);
266268
if (ret)

0 commit comments

Comments
 (0)