2021-09-10 16:56:24

by Xin Xiong

[permalink] [raw]
Subject: [PATCH] drivers/mtd/nand: fix reference count leaks in ebu_nand_probe

The reference counting issue happens in several error handling paths
on two refcounted object related to the "ebu_host" object (dma_tx,
dma_rx). In these paths, the function forgets to balance one or both
objects' reference count. For example, when request dma tx chan fails,
the function forgets to decrease the refcount of "ebu_host->dma_rx"
increased by dma_request_chan(), causing refcount leaks. What's more,
the "ebu_host->clk" object also need to be handled correctly.

Fix this issue by keeping the return value and jumping to
"err_cleanup_dma" label.

Signed-off-by: Xin Xiong <[email protected]>
Signed-off-by: Xiyu Yang <[email protected]>
Signed-off-by: Xin Tan <[email protected]>
---
drivers/mtd/nand/raw/intel-nand-controller.c | 23 ++++++++++++++------
1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/intel-nand-controller.c b/drivers/mtd/nand/raw/intel-nand-controller.c
index 8b49fd56c..d5148f220 100644
--- a/drivers/mtd/nand/raw/intel-nand-controller.c
+++ b/drivers/mtd/nand/raw/intel-nand-controller.c
@@ -631,19 +631,27 @@ static int ebu_nand_probe(struct platform_device *pdev)
ebu_host->clk_rate = clk_get_rate(ebu_host->clk);

ebu_host->dma_tx = dma_request_chan(dev, "tx");
- if (IS_ERR(ebu_host->dma_tx))
- return dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx),
+ if (IS_ERR(ebu_host->dma_tx)) {
+ ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_tx),
"failed to request DMA tx chan!.\n");
+ ebu_host->dma_tx = NULL;
+ goto err_cleanup_dma;
+ }

ebu_host->dma_rx = dma_request_chan(dev, "rx");
- if (IS_ERR(ebu_host->dma_rx))
- return dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx),
+ if (IS_ERR(ebu_host->dma_rx)) {
+ ret = dev_err_probe(dev, PTR_ERR(ebu_host->dma_rx),
"failed to request DMA rx chan!.\n");
+ ebu_host->dma_rx = NULL;
+ goto err_cleanup_dma;
+ }

resname = devm_kasprintf(dev, GFP_KERNEL, "addr_sel%d", cs);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, resname);
- if (!res)
- return -EINVAL;
+ if (!res) {
+ ret = -EINVAL;
+ goto err_cleanup_dma;
+ }
ebu_host->cs[cs].addr_sel = res->start;
writel(ebu_host->cs[cs].addr_sel | EBU_ADDR_MASK(5) | EBU_ADDR_SEL_REGEN,
ebu_host->ebu + EBU_ADDR_SEL(cs));
@@ -653,7 +661,8 @@ static int ebu_nand_probe(struct platform_device *pdev)
mtd = nand_to_mtd(&ebu_host->chip);
if (!mtd->name) {
dev_err(ebu_host->dev, "NAND label property is mandatory\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_cleanup_dma;
}

mtd->dev.parent = dev;
--
2.25.1


2021-09-14 17:06:44

by Miquel Raynal

[permalink] [raw]
Subject: Re: [PATCH] drivers/mtd/nand: fix reference count leaks in ebu_nand_probe

Hello,

[email protected] wrote on Sat, 11 Sep 2021 00:53:16 +0800:

> The reference counting issue happens in several error handling paths
> on two refcounted object related to the "ebu_host" object (dma_tx,
> dma_rx). In these paths, the function forgets to balance one or both
> objects' reference count. For example, when request dma tx chan fails,
> the function forgets to decrease the refcount of "ebu_host->dma_rx"
> increased by dma_request_chan(), causing refcount leaks. What's more,
> the "ebu_host->clk" object also need to be handled correctly.
>
> Fix this issue by keeping the return value and jumping to
> "err_cleanup_dma" label.

I think it has already been fixed upstream:
0792ec82175e ("mtd: rawnand: intel: Fix error handling in probe")

Thanks,
Miquèl