Skip to content

Commit f5c24d9

Browse files
ADESTMvinodkoul
authored andcommitted
dmaengine: fix NULL pointer in channel unregistration function
__dma_async_device_channel_register() can fail. In case of failure, chan->local is freed (with free_percpu()), and chan->local is nullified. When dma_async_device_unregister() is called (because of managed API or intentionally by DMA controller driver), channels are unconditionally unregistered, leading to this NULL pointer: [ 1.318693] Unable to handle kernel NULL pointer dereference at virtual address 00000000000000d0 [...] [ 1.484499] Call trace: [ 1.486930] device_del+0x40/0x394 [ 1.490314] device_unregister+0x20/0x7c [ 1.494220] __dma_async_device_channel_unregister+0x68/0xc0 Look at dma_async_device_register() function error path, channel device unregistration is done only if chan->local is not NULL. Then add the same condition at the beginning of __dma_async_device_channel_unregister() function, to avoid NULL pointer issue whatever the API used to reach this function. Fixes: d2fb0a0 ("dmaengine: break out channel registration") Signed-off-by: Amelie Delaunay <[email protected]> Reviewed-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent d0e217b commit f5c24d9

File tree

1 file changed

+3
-0
lines changed

1 file changed

+3
-0
lines changed

drivers/dma/dmaengine.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,6 +1103,9 @@ EXPORT_SYMBOL_GPL(dma_async_device_channel_register);
11031103
static void __dma_async_device_channel_unregister(struct dma_device *device,
11041104
struct dma_chan *chan)
11051105
{
1106+
if (chan->local == NULL)
1107+
return;
1108+
11061109
WARN_ONCE(!device->device_release && chan->client_count,
11071110
"%s called while %d clients hold a reference\n",
11081111
__func__, chan->client_count);

0 commit comments

Comments
 (0)