diff options
author | Lv Yunlong <lyl2019@mail.ustc.edu.cn> | 2021-03-31 04:44:58 +0300 |
---|---|---|
committer | Vinod Koul <vkoul@kernel.org> | 2021-04-12 12:35:58 +0300 |
commit | ea45b6008f8095db0cc09ad6e03c7785c2986197 (patch) | |
tree | 36bfe6e35d915dd751f57f802f9067e256109668 /drivers/dma/dmaengine.c | |
parent | 88cd1d6191b13689094310c2405394e4ce36d061 (diff) | |
download | linux-ea45b6008f8095db0cc09ad6e03c7785c2986197.tar.xz |
dmaengine: Fix a double free in dma_async_device_register
In the first list_for_each_entry() macro of dma_async_device_register,
it gets the chan from list and calls __dma_async_device_channel_register
(..,chan). We can see that chan->local is allocated by alloc_percpu() and
it is freed chan->local by free_percpu(chan->local) when
__dma_async_device_channel_register() failed.
But after __dma_async_device_channel_register() failed, the caller will
goto err_out and freed the chan->local in the second time by free_percpu().
The cause of this problem is forget to set chan->local to NULL when
chan->local was freed in __dma_async_device_channel_register(). My
patch sets chan->local to NULL when the callee failed to avoid double free.
Fixes: d2fb0a0438384 ("dmaengine: break out channel registration")
Signed-off-by: Lv Yunlong <lyl2019@mail.ustc.edu.cn>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Link: https://lore.kernel.org/r/20210331014458.3944-1-lyl2019@mail.ustc.edu.cn
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Diffstat (limited to 'drivers/dma/dmaengine.c')
-rw-r--r-- | drivers/dma/dmaengine.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index fe6a460c4373..af3ee288bc11 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -1086,6 +1086,7 @@ static int __dma_async_device_channel_register(struct dma_device *device, kfree(chan->dev); err_free_local: free_percpu(chan->local); + chan->local = NULL; return rc; } |