[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20251028054437.759728-1-niravkumarlaxmidas.rabara@altera.com>
Date: Tue, 28 Oct 2025 13:44:37 +0800
From: niravkumarlaxmidas.rabara@...era.com
To: miquel.raynal@...tlin.com,
richard@....at,
vigneshr@...com
Cc: linux-mtd@...ts.infradead.org,
linux-kernel@...r.kernel.org,
Niravkumar L Rabara <niravkumarlaxmidas.rabara@...era.com>,
Dan Carpenter <dan.carpenter@...aro.org>
Subject: [PATCH] mtd: rawnand: cadence: avoid NULL dereference of DMA device pointer
From: Niravkumar L Rabara <niravkumarlaxmidas.rabara@...era.com>
The cdns_ctrl->dmac->device was accessed unconditionally, even when
'has_dma' is false and cdns_ctrl->dmac is not assigned. This could lead to
a NULL pointer dereference when DMA is not used.
Rework the logic so that DMA mapping and unmapping are performed only when
cdns_ctrl->dmac is valid. When DMA is not used, the I/O resource address
is used directly. Also a proper check is added before calling
dma_unmap_resource().
Fixes: 5c56bf214af8 ("mtd: rawnand: cadence: fix DMA device NULL pointer dereference")
Reported-by: Dan Carpenter <dan.carpenter@...aro.org>
Closes: https://lore.kernel.org/all/aP8S9oEgMv6PXzax@stanley.mountain/
Signed-off-by: Niravkumar L Rabara <niravkumarlaxmidas.rabara@...era.com>
---
- The changes were verified using Smatch and tested on the Intel Agilex5
SoCFPGA development kit.
.../mtd/nand/raw/cadence-nand-controller.c | 27 ++++++++++---------
1 file changed, 15 insertions(+), 12 deletions(-)
diff --git a/drivers/mtd/nand/raw/cadence-nand-controller.c b/drivers/mtd/nand/raw/cadence-nand-controller.c
index 32ed38b89394..5a40e0560984 100644
--- a/drivers/mtd/nand/raw/cadence-nand-controller.c
+++ b/drivers/mtd/nand/raw/cadence-nand-controller.c
@@ -2871,7 +2871,6 @@ cadence_nand_irq_cleanup(int irqnum, struct cdns_nand_ctrl *cdns_ctrl)
static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
{
dma_cap_mask_t mask;
- struct dma_device *dma_dev;
int ret;
cdns_ctrl->cdma_desc = dma_alloc_coherent(cdns_ctrl->dev,
@@ -2913,17 +2912,19 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
"%d: Failed to get a DMA channel\n", ret);
goto disable_irq;
}
- }
- dma_dev = cdns_ctrl->dmac->device;
- cdns_ctrl->io.iova_dma = dma_map_resource(dma_dev->dev, cdns_ctrl->io.dma,
- cdns_ctrl->io.size,
- DMA_BIDIRECTIONAL, 0);
+ cdns_ctrl->io.iova_dma = dma_map_resource(cdns_ctrl->dmac->device->dev,
+ cdns_ctrl->io.dma, cdns_ctrl->io.size,
+ DMA_BIDIRECTIONAL, 0);
- ret = dma_mapping_error(dma_dev->dev, cdns_ctrl->io.iova_dma);
- if (ret) {
- dev_err(cdns_ctrl->dev, "Failed to map I/O resource to DMA\n");
- goto dma_release_chnl;
+ ret = dma_mapping_error(cdns_ctrl->dmac->device->dev,
+ cdns_ctrl->io.iova_dma);
+ if (ret) {
+ dev_err(cdns_ctrl->dev, "Failed to map I/O resource to DMA\n");
+ goto dma_release_chnl;
+ }
+ } else {
+ cdns_ctrl->io.iova_dma = cdns_ctrl->io.dma;
}
nand_controller_init(&cdns_ctrl->controller);
@@ -2949,8 +2950,10 @@ static int cadence_nand_init(struct cdns_nand_ctrl *cdns_ctrl)
return 0;
unmap_dma_resource:
- dma_unmap_resource(dma_dev->dev, cdns_ctrl->io.iova_dma,
- cdns_ctrl->io.size, DMA_BIDIRECTIONAL, 0);
+ if (cdns_ctrl->dmac && cdns_ctrl->dmac->device)
+ dma_unmap_resource(cdns_ctrl->dmac->device->dev,
+ cdns_ctrl->io.iova_dma, cdns_ctrl->io.size,
+ DMA_BIDIRECTIONAL, 0);
dma_release_chnl:
if (cdns_ctrl->dmac)
--
2.25.1
Powered by blists - more mailing lists