lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Sat, 11 Sep 2021 00:53:16 +0800 From: Xin Xiong <xiongx18@...an.edu.cn> To: Miquel Raynal <miquel.raynal@...tlin.com>, Richard Weinberger <richard@....at>, Vignesh Raghavendra <vigneshr@...com>, linux-mtd@...ts.infradead.org, linux-kernel@...r.kernel.org Cc: yuanxzhang@...an.edu.cn, Xin Xiong <xiongx18@...an.edu.cn>, Xiyu Yang <xiyuyang19@...an.edu.cn>, Xin Tan <tanxin.ctf@...il.com> 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 <xiongx18@...an.edu.cn> Signed-off-by: Xiyu Yang <xiyuyang19@...an.edu.cn> Signed-off-by: Xin Tan <tanxin.ctf@...il.com> --- 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
Powered by blists - more mailing lists