| From e2244d7f24535989ecd72a6e4517b454a8558d12 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 9 Oct 2021 12:19:18 +0800 |
| Subject: mmc: moxart: Fix reference count leaks in moxart_probe |
| |
| From: Xin Xiong <xiongx18@fudan.edu.cn> |
| |
| [ 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> |
| --- |
| drivers/mmc/host/moxart-mmc.c | 16 ++++++++++++++-- |
| 1 file changed, 14 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/mmc/host/moxart-mmc.c b/drivers/mmc/host/moxart-mmc.c |
| index 6c9d38132f74c..7b9fcef490de7 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); |
| -- |
| 2.33.0 |
| |