diff options
author | Xin Xiong <xiongx18@fudan.edu.cn> | 2021-10-09 12:19:18 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-11-18 19:16:15 +0100 |
commit | d78de051ff328f98cd534d4bc1bfee1f4f829f61 (patch) | |
tree | 70f5f9537f1ea6142bf9ca5936fc8f1486df137e /drivers/mmc | |
parent | e41d46fe0954ec4ae806f8b815bf70929d5c5657 (diff) |
mmc: moxart: Fix reference count leaks in moxart_probe
[ Upstream commit 8105c2abbf36296bf38ca44f55ee45d160db476a ]
The issue happens in several error handling paths on two refcounted
object related to the object "host" (dma_chan_rx, dma_chan_tx). In
these paths, the function forgets to decrement one or both objects'
reference count increased earlier by dma_request_chan(), causing
reference count leaks.
Fix it by balancing the refcounts of both objects in some error
handling paths. In correspondence with the changes in moxart_probe(),
IS_ERR() is replaced with IS_ERR_OR_NULL() in moxart_remove() as well.
Signed-off-by: Xin Xiong <xiongx18@fudan.edu.cn>
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
Link: https://lore.kernel.org/r/20211009041918.28419-1-xiongx18@fudan.edu.cn
Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/host/moxart-mmc.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c index 6c9d38132f74..7b9fcef490de 100644 --- a/drivers/mmc/host/moxart-mmc.c +++ b/drivers/mmc/host/moxart-mmc.c @@ -621,6 +621,14 @@ static int moxart_probe(struct platform_device *pdev) ret = -EPROBE_DEFER; goto out; } + if (!IS_ERR(host->dma_chan_tx)) { + dma_release_channel(host->dma_chan_tx); + host->dma_chan_tx = NULL; + } + if (!IS_ERR(host->dma_chan_rx)) { + dma_release_channel(host->dma_chan_rx); + host->dma_chan_rx = NULL; + } dev_dbg(dev, "PIO mode transfer enabled\n"); host->have_dma = false; } else { @@ -675,6 +683,10 @@ static int moxart_probe(struct platform_device *pdev) return 0; out: + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) + dma_release_channel(host->dma_chan_tx); + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) + dma_release_channel(host->dma_chan_rx); if (mmc) mmc_free_host(mmc); return ret; @@ -687,9 +699,9 @@ static int moxart_remove(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, NULL); - if (!IS_ERR(host->dma_chan_tx)) + if (!IS_ERR_OR_NULL(host->dma_chan_tx)) dma_release_channel(host->dma_chan_tx); - if (!IS_ERR(host->dma_chan_rx)) + if (!IS_ERR_OR_NULL(host->dma_chan_rx)) dma_release_channel(host->dma_chan_rx); mmc_remove_host(mmc); mmc_free_host(mmc); |