[PATCH 10/10] EDAC/altera: Fix error cleanup path in altr_edac_device_probe()

Dinh Nguyen <[email protected]> Mon, 27 Jul 2026 08:24:16 -0500
Newsgroups org.kernel.vger.linux-edac,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
sashiko reports: Does the error cleanup path in
altr_edac_device_probe() free data before unregistering the interrupt
handler? If a failure occurs, dci is explicitly freed via
edac_device_free_ctl_info(dci) before the managed IRQ handler is unregistered
via devres_release_group(). If an interrupt fires in this window, could it
dereference the freed dci?

Clean up the fail1 path to always call devres_release_group() and
conditionally free the dci.

Fixes: c3eea1942a16 ("EDAC, altera: Add Altera L2 cache and OCRAM support")
Cc: [email protected]
Signed-off-by: Dinh Nguyen <[email protected]>
---
 drivers/edac/altera_edac.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 80ca9f511ac98..b6048a1884f43 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -701,7 +701,7 @@ MODULE_DEVICE_TABLE(of, altr_edac_device_of_match);
  */
 static int altr_edac_device_probe(struct platform_device *pdev)
 {
-	struct edac_device_ctl_info *dci;
+	struct edac_device_ctl_info *dci = NULL;
 	struct altr_edac_device_dev *drvdata;
 	struct resource *r;
 	int res = 0;
@@ -729,7 +729,7 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 		edac_printk(KERN_ERR, EDAC_DEVICE,
 			    "Unable to get mem resource\n");
 		res = -ENODEV;
-		goto fail;
+		goto fail1;
 	}
 
 	if (!devm_request_mem_region(&pdev->dev, r->start, resource_size(r),
@@ -737,7 +737,7 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 		edac_printk(KERN_ERR, EDAC_DEVICE,
 			    "%s:Error requesting mem region\n", ecc_name);
 		res = -EBUSY;
-		goto fail;
+		goto fail1;
 	}
 
 	dci = edac_device_alloc_ctl_info(sizeof(*drvdata), ecc_name,
@@ -747,7 +747,7 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 		edac_printk(KERN_ERR, EDAC_DEVICE,
 			    "%s: Unable to allocate EDAC device\n", ecc_name);
 		res = -ENOMEM;
-		goto fail;
+		goto fail1;
 	}
 
 	drvdata = dci->pvt_info;
@@ -806,9 +806,9 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 	return 0;
 
 fail1:
-	edac_device_free_ctl_info(dci);
-fail:
 	devres_release_group(&pdev->dev, NULL);
+	if (dci)
+		edac_device_free_ctl_info(dci);
 	edac_printk(KERN_ERR, EDAC_DEVICE,
 		    "%s:Error setting up EDAC device: %d\n", ecc_name, res);
 
-- 
2.42.0.411.g813d9a9188