Linux EDAC development
 help / color / mirror / Atom feed
* [PATCHv2 0/4] EDAC/altera: Address sashiko reviews part 1(v2)
@ 2026-08-06 15:54 Dinh Nguyen
  2026-08-06 15:54 ` [PATCHv2 1/4] EDAC/altera: Add suppress_bind_attrs so driver cannot get unbound Dinh Nguyen
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Dinh Nguyen @ 2026-08-06 15:54 UTC (permalink / raw)
  To: bp, tony.luck
  Cc: dinguyen, rounakdas2025, niravkumar.l.rabara, linux-edac,
	linux-kernel

Hi EDAC maintainers,

This is version 2 of the patch series that addresses some of the sashiko
reviews for the Altera EDAC driver.

I apologize for the lateness of this series, but I do believe these 4
patches are important enough to be included in v7.2 because they are
confirmed bug hits.

patch 1/4 : EDAC/altera: Add suppress_bind_attrs so driver cannot get unbound
While sashiko did not flag this specific feature of the driver, the
reviews caused me to look at the bind/unbind feature of this driver. The
unbind/bind feature will absolutely cause a system to crash because
during the bind, the driver sets a bit to clear the memory. We
absolutely cannot do this on a running system.

patch 2/4 : EDAC/altera: Drop __init from ECC setup paths for re-probe safety
For all the different child nodes of the main EDAC module, there is a
chance for deferred probing. If EPROBE_DEFER occurs, and these functions
that are marked with __init will be freed.

patch 3/4 : EDAC/altera: Fix code leak on dci allocation failure
The dci data structure is leaked if a devres_open_group() fails.

patch 4/4 : EDAC/altera: Fix use-after-free in error paths
The dci structure cannot be freed before the unregistering of the
interrupts.


Dinh Nguyen (4):
  EDAC/altera: Add suppress_bind_attrs so driver cannot get unbound
  EDAC/altera: Drop __init from ECC setup paths for re-probe safety
  EDAC/altera: Fix code leak on dci allocation failure
  EDAC/altera: Fix use-after-free in error paths

 drivers/edac/altera_edac.c | 60 ++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 31 deletions(-)

-- 
2.42.0.411.g813d9a9188


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCHv2 1/4] EDAC/altera: Add suppress_bind_attrs so driver cannot get unbound
  2026-08-06 15:54 [PATCHv2 0/4] EDAC/altera: Address sashiko reviews part 1(v2) Dinh Nguyen
@ 2026-08-06 15:54 ` Dinh Nguyen
  2026-08-06 15:54 ` [PATCHv2 2/4] EDAC/altera: Drop __init from ECC setup paths for re-probe safety Dinh Nguyen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Dinh Nguyen @ 2026-08-06 15:54 UTC (permalink / raw)
  To: bp, tony.luck
  Cc: dinguyen, rounakdas2025, niravkumar.l.rabara, linux-edac,
	linux-kernel, stable

The EDAC driver should not be able to be removed from userspace because a
re-bind would clear out existing memory contents of an active running system.

With this change, remove the .remove functions because they will not
ever get used.

Fixes: 588cb03ea208 ("EDAC, altera: Add Arria10 L2 Cache ECC handling")
Cc: stable@vger.kernel.org
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
 drivers/edac/altera_edac.c | 25 ++++---------------------
 1 file changed, 4 insertions(+), 21 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index 68846f583eeef..fe501c89dd0dc 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -453,15 +453,6 @@ static int altr_sdram_probe(struct platform_device *pdev)
 	return res;
 }
 
-static void altr_sdram_remove(struct platform_device *pdev)
-{
-	struct mem_ctl_info *mci = platform_get_drvdata(pdev);
-
-	edac_mc_del_mc(&pdev->dev);
-	edac_mc_free(mci);
-	platform_set_drvdata(pdev, NULL);
-}
-
 /*
  * If you want to suspend, need to disable EDAC by removing it
  * from the device tree or defconfig.
@@ -481,13 +472,13 @@ static const struct dev_pm_ops altr_sdram_pm_ops = {
 
 static struct platform_driver altr_sdram_edac_driver = {
 	.probe = altr_sdram_probe,
-	.remove = altr_sdram_remove,
 	.driver = {
 		.name = "altr_sdram_edac",
 #ifdef CONFIG_PM
 		.pm = &altr_sdram_pm_ops,
 #endif
 		.of_match_table = altr_sdram_ctrl_of_match,
+		.suppress_bind_attrs = true,
 	},
 };
 
@@ -517,6 +508,7 @@ static struct platform_driver altr_edac_driver = {
 	.driver = {
 		.name = "socfpga_ecc_manager",
 		.of_match_table = altr_edac_of_match,
+		.suppress_bind_attrs = true,
 	},
 };
 module_platform_driver(altr_edac_driver);
@@ -803,22 +795,12 @@ static int altr_edac_device_probe(struct platform_device *pdev)
 	return res;
 }
 
-static void altr_edac_device_remove(struct platform_device *pdev)
-{
-	struct edac_device_ctl_info *dci = platform_get_drvdata(pdev);
-	struct altr_edac_device_dev *drvdata = dci->pvt_info;
-
-	debugfs_remove_recursive(drvdata->debugfs_dir);
-	edac_device_del_device(&pdev->dev);
-	edac_device_free_ctl_info(dci);
-}
-
 static struct platform_driver altr_edac_device_driver = {
 	.probe =  altr_edac_device_probe,
-	.remove = altr_edac_device_remove,
 	.driver = {
 		.name = "altr_edac_device",
 		.of_match_table = altr_edac_device_of_match,
+		.suppress_bind_attrs = true,
 	},
 };
 module_platform_driver(altr_edac_device_driver);
@@ -2214,6 +2196,7 @@ static struct platform_driver altr_edac_a10_driver = {
 	.driver = {
 		.name = "socfpga_a10_ecc_manager",
 		.of_match_table = altr_edac_a10_of_match,
+		.suppress_bind_attrs = true,
 	},
 };
 module_platform_driver(altr_edac_a10_driver);
-- 
2.42.0.411.g813d9a9188


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCHv2 2/4] EDAC/altera: Drop __init from ECC setup paths for re-probe safety
  2026-08-06 15:54 [PATCHv2 0/4] EDAC/altera: Address sashiko reviews part 1(v2) Dinh Nguyen
  2026-08-06 15:54 ` [PATCHv2 1/4] EDAC/altera: Add suppress_bind_attrs so driver cannot get unbound Dinh Nguyen
@ 2026-08-06 15:54 ` Dinh Nguyen
  2026-08-06 15:54 ` [PATCHv2 3/4] EDAC/altera: Fix code leak on dci allocation failure Dinh Nguyen
  2026-08-06 15:54 ` [PATCHv2 4/4] EDAC/altera: Fix use-after-free in error paths Dinh Nguyen
  3 siblings, 0 replies; 6+ messages in thread
From: Dinh Nguyen @ 2026-08-06 15:54 UTC (permalink / raw)
  To: bp, tony.luck
  Cc: dinguyen, rounakdas2025, niravkumar.l.rabara, linux-edac,
	linux-kernel, stable

sashiko reports: Does suppressing sysfs unbinding fully prevent the
execution of freed __init memory? If altr_sysmgr_regmap_lookup_by_phandle()
returns -EPROBE_DEFER, the probe is deferred until after __init memory is
freed.

The a10 EDAC .setup callbacks (sdmmc, ethernet, nand, dma, usb, qspi)
and their helpers (altr_init_a10_ecc_device_type,
altr_init_a10_ecc_block) were marked __init. These run from the probe
path, which may execute after init memory is freed -- e.g. a probe
deferred via -EPROBE_DEFER that only succeeds once a late/module
dependency appears, or a manual unbind/rebind. Calling __init code then
dereferences freed memory. Remove __init so these functions remain
valid at runtime.

Assisted-by: Cursor:claude-4.8-opus
Fixes: 788586efd116 ("EDAC/altera: Initialize peripheral FIFOs in probe()")
Cc: stable@vger.kernel.org
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
 drivers/edac/altera_edac.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index fe501c89dd0dc..d8a3438fb5f44 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -926,7 +926,7 @@ static int __maybe_unused altr_init_memory_port(void __iomem *ioaddr, int port)
 	return ret;
 }
 
-static __init int __maybe_unused
+static int __maybe_unused
 altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask,
 			u32 ecc_ctrl_en_mask, bool dual_port)
 {
@@ -1001,7 +1001,7 @@ altr_init_a10_ecc_block(struct device_node *np, u32 irq_mask,
 
 static int validate_parent_available(struct device_node *np);
 static const struct of_device_id altr_edac_a10_device_of_match[];
-static int __init __maybe_unused altr_init_a10_ecc_device_type(char *compat)
+static int __maybe_unused altr_init_a10_ecc_device_type(char *compat)
 {
 	int irq;
 	struct device_node *child, *np;
@@ -1330,7 +1330,7 @@ static const struct edac_device_prv_data a10_l2ecc_data = {
 
 #ifdef CONFIG_EDAC_ALTERA_ETHERNET
 
-static int __init socfpga_init_ethernet_ecc(struct altr_edac_device_dev *dev)
+static int socfpga_init_ethernet_ecc(struct altr_edac_device_dev *dev)
 {
 	int ret;
 
@@ -1360,7 +1360,7 @@ static const struct edac_device_prv_data a10_enetecc_data = {
 
 #ifdef CONFIG_EDAC_ALTERA_NAND
 
-static int __init socfpga_init_nand_ecc(struct altr_edac_device_dev *device)
+static int socfpga_init_nand_ecc(struct altr_edac_device_dev *device)
 {
 	int ret;
 
@@ -1390,7 +1390,7 @@ static const struct edac_device_prv_data a10_nandecc_data = {
 
 #ifdef CONFIG_EDAC_ALTERA_DMA
 
-static int __init socfpga_init_dma_ecc(struct altr_edac_device_dev *device)
+static int socfpga_init_dma_ecc(struct altr_edac_device_dev *device)
 {
 	int ret;
 
@@ -1420,7 +1420,7 @@ static const struct edac_device_prv_data a10_dmaecc_data = {
 
 #ifdef CONFIG_EDAC_ALTERA_USB
 
-static int __init socfpga_init_usb_ecc(struct altr_edac_device_dev *device)
+static int socfpga_init_usb_ecc(struct altr_edac_device_dev *device)
 {
 	int ret;
 
@@ -1450,7 +1450,7 @@ static const struct edac_device_prv_data a10_usbecc_data = {
 
 #ifdef CONFIG_EDAC_ALTERA_QSPI
 
-static int __init socfpga_init_qspi_ecc(struct altr_edac_device_dev *device)
+static int socfpga_init_qspi_ecc(struct altr_edac_device_dev *device)
 {
 	int ret;
 
@@ -1598,7 +1598,7 @@ static int altr_portb_setup(struct altr_edac_device_dev *device)
 	return rc;
 }
 
-static int __init socfpga_init_sdmmc_ecc(struct altr_edac_device_dev *device)
+static int socfpga_init_sdmmc_ecc(struct altr_edac_device_dev *device)
 {
 	int rc = -ENODEV;
 	struct device_node *child;
-- 
2.42.0.411.g813d9a9188


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCHv2 3/4] EDAC/altera: Fix code leak on dci allocation failure
  2026-08-06 15:54 [PATCHv2 0/4] EDAC/altera: Address sashiko reviews part 1(v2) Dinh Nguyen
  2026-08-06 15:54 ` [PATCHv2 1/4] EDAC/altera: Add suppress_bind_attrs so driver cannot get unbound Dinh Nguyen
  2026-08-06 15:54 ` [PATCHv2 2/4] EDAC/altera: Drop __init from ECC setup paths for re-probe safety Dinh Nguyen
@ 2026-08-06 15:54 ` Dinh Nguyen
  2026-08-06 18:16   ` Rounak Das
  2026-08-06 15:54 ` [PATCHv2 4/4] EDAC/altera: Fix use-after-free in error paths Dinh Nguyen
  3 siblings, 1 reply; 6+ messages in thread
From: Dinh Nguyen @ 2026-08-06 15:54 UTC (permalink / raw)
  To: bp, tony.luck
  Cc: dinguyen, rounakdas2025, niravkumar.l.rabara, linux-edac,
	linux-kernel, stable

sashiko reports: If devres_open_group() fails, the function returns -ENOMEM
without freeing the dci structure allocated earlier with edac_device_alloc_ctl_info().

Free the dci structure if devres_open_group() fails.

Fixes: c3eea1942a16 ("EDAC, altera: Add Altera L2 cache and OCRAM support")
Cc: stable@vger.kernel.org
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
 drivers/edac/altera_edac.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index d8a3438fb5f44..ccdfb35178b69 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -1516,8 +1516,10 @@ static int altr_portb_setup(struct altr_edac_device_dev *device)
 	altdev = dci->pvt_info;
 	*altdev = *device;
 
-	if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL))
+	if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL)) {
+		edac_device_free_ctl_info(dci);
 		return -ENOMEM;
+	}
 
 	/* Update PortB specific values */
 	altdev->edac_dev_name = ecc_name;
-- 
2.42.0.411.g813d9a9188


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCHv2 4/4] EDAC/altera: Fix use-after-free in error paths
  2026-08-06 15:54 [PATCHv2 0/4] EDAC/altera: Address sashiko reviews part 1(v2) Dinh Nguyen
                   ` (2 preceding siblings ...)
  2026-08-06 15:54 ` [PATCHv2 3/4] EDAC/altera: Fix code leak on dci allocation failure Dinh Nguyen
@ 2026-08-06 15:54 ` Dinh Nguyen
  3 siblings, 0 replies; 6+ messages in thread
From: Dinh Nguyen @ 2026-08-06 15:54 UTC (permalink / raw)
  To: bp, tony.luck
  Cc: dinguyen, rounakdas2025, niravkumar.l.rabara, linux-edac,
	linux-kernel, stable

In both altr_edac_a10_device_add() and altr_portb_setup(), the error path
freed the dci structure before releasing the devres group. Since the managed
single and double bit IRQ handlers use altdev(dci->pvt_info) as their data, an
IRQ firing between freeing dci and unregistering the IRQs could dereference
the freed memory.

Release the devres group first so the managed IRQs are unregistered
before the dci structure is freed.

Assisted-by: Cursor:claude-4.8-opus
Fixes: 911049845d70 ("EDAC, altera: Add Arria10 SD-MMC EDAC support")
Fixes: 588cb03ea208 ("EDAC, altera: Add Arria10 L2 Cache ECC handling")
Closes: https://sashiko.dev/#/patchset/20260719211238.589402-1-rosenp%40gmail.com
Cc: stable@vger.kernel.org
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
 drivers/edac/altera_edac.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c
index ccdfb35178b69..4c20fb9261608 100644
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -1593,8 +1593,13 @@ static int altr_portb_setup(struct altr_edac_device_dev *device)
 	return 0;
 
 err_release_group_1:
-	edac_device_free_ctl_info(dci);
+	/*
+	 * Release the devres group first so the managed IRQs are
+	 * unregistered before dci (which contains the IRQ handler's
+	 * data via dci->pvt_info) is freed, avoiding a use-after-free.
+	 */
 	devres_release_group(device->edac->dev, altr_portb_setup);
+	edac_device_free_ctl_info(dci);
 	edac_printk(KERN_ERR, EDAC_DEVICE,
 		    "%s:Error setting up EDAC device: %d\n", ecc_name, rc);
 	return rc;
@@ -1997,9 +2002,17 @@ static int altr_edac_a10_device_add(struct altr_arria10_edac *edac,
 	return 0;
 
 err_release_group1:
+	/*
+	 * Release the devres group first so the managed IRQs are
+	 * unregistered before dci (which contains the IRQ handler's
+	 * data via dci->pvt_info) is freed, avoiding a use-after-free.
+	 */
+	devres_release_group(edac->dev, NULL);
 	edac_device_free_ctl_info(dci);
+	goto err_print;
 err_release_group:
 	devres_release_group(edac->dev, NULL);
+err_print:
 	edac_printk(KERN_ERR, EDAC_DEVICE,
 		    "%s:Error setting up EDAC device: %d\n", ecc_name, rc);
 
-- 
2.42.0.411.g813d9a9188


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCHv2 3/4] EDAC/altera: Fix code leak on dci allocation failure
  2026-08-06 15:54 ` [PATCHv2 3/4] EDAC/altera: Fix code leak on dci allocation failure Dinh Nguyen
@ 2026-08-06 18:16   ` Rounak Das
  0 siblings, 0 replies; 6+ messages in thread
From: Rounak Das @ 2026-08-06 18:16 UTC (permalink / raw)
  To: Dinh Nguyen; +Cc: bp, tony.luck, niravkumar.l.rabara, linux-edac, linux-kernel

Hi Dinh,

> -       if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL))
> +       if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL)) {
> +               edac_device_free_ctl_info(dci);
>                 return -ENOMEM;
> +       }

This overlaps with my of_node_put fix that was acked on 2026-07-20
(20260717131720.19038-1-rounakdas2025@gmail.com), which was held
until the sashiko issues were addressed.

Patches 3/4 and 4/4 touch the same two hunks in altr_portb_setup(): the
devres_open_group() failure path and the err_release_group_1 label. Both
changes are needed in the first one, i.e.

    if (!devres_open_group(...)) {
        edac_device_free_ctl_info(dci);
        of_node_put(np);
        return -ENOMEM;
    }

so whichever goes in second will need a rebase. Happy to resend mine on
top of this series if that ordering is easier.

Thanks,
Rounak

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-06 18:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-06 15:54 [PATCHv2 0/4] EDAC/altera: Address sashiko reviews part 1(v2) Dinh Nguyen
2026-08-06 15:54 ` [PATCHv2 1/4] EDAC/altera: Add suppress_bind_attrs so driver cannot get unbound Dinh Nguyen
2026-08-06 15:54 ` [PATCHv2 2/4] EDAC/altera: Drop __init from ECC setup paths for re-probe safety Dinh Nguyen
2026-08-06 15:54 ` [PATCHv2 3/4] EDAC/altera: Fix code leak on dci allocation failure Dinh Nguyen
2026-08-06 18:16   ` Rounak Das
2026-08-06 15:54 ` [PATCHv2 4/4] EDAC/altera: Fix use-after-free in error paths Dinh Nguyen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox