From: Rosen Penev <rosenp@gmail.com>
To: linux-edac@vger.kernel.org
Cc: Frank Li <Frank.Li@nxp.com>, Borislav Petkov <bp@alien8.de>,
Tony Luck <tony.luck@intel.com>,
Nathan Chancellor <nathan@kernel.org>,
Nick Desaulniers <ndesaulniers@google.com>,
Bill Wendling <morbo@google.com>,
Justin Stitt <justinstitt@google.com>,
York Sun <york.sun@nxp.com>,
imx@lists.linux.dev (open list:EDAC-FSL_DDR),
linux-kernel@vger.kernel.org (open list),
llvm@lists.linux.dev (open list:CLANG/LLVM BUILD
SUPPORT:Keyword:\b(?i:clang|llvm)\b)
Subject: [PATCH 2/2] EDAC: fsl_ddr: manage mci lifetime via devres to fix remove UAF
Date: Sun, 19 Jul 2026 12:40:09 -0700 [thread overview]
Message-ID: <20260719194009.117532-3-rosenp@gmail.com> (raw)
In-Reply-To: <20260719194009.117532-1-rosenp@gmail.com>
fsl_mc_err_probe() requests the shared interrupt with devm_request_irq(),
passing mci as the handler context. At removal fsl_mc_err_remove() calls
edac_mc_free(mci) explicitly, but the devm-requested IRQ is only torn
down by devres afterwards. Between edac_mc_free() and the IRQ release,
another device sharing the line can fire and fsl_mc_isr() will
dereference the freed mci and its pdata.
Register an edac_mc_free() callback via devm_add_action_or_reset() right
after edac_mc_alloc(), so mci is owned by devres and freed only after the
devm IRQ is released (devres runs actions in LIFO order). Drop the
explicit edac_mc_free() from both the probe error paths and
fsl_mc_err_remove(); edac_mc_del_mc() is still called explicitly at
remove time so the edac device is unregistered before the deferred free.
This also lets the now-redundant devres group open/release/remove calls
be removed.
Built for arm64 (defconfig + CONFIG_EDAC_FSL_DDR) with LLVM=1;
drivers/edac/fsl_ddr_edac.o compiles cleanly and passes checkpatch --strict.
Fixes: ea2eb9a8b620 ("EDAC, fsl-ddr: Separate FSL DDR driver from MPC85xx")
Assisted-by: opencode:hy3-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
drivers/edac/fsl_ddr_edac.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/edac/fsl_ddr_edac.c b/drivers/edac/fsl_ddr_edac.c
index b1e6e177b088..cdd129bc42c7 100644
--- a/drivers/edac/fsl_ddr_edac.c
+++ b/drivers/edac/fsl_ddr_edac.c
@@ -490,6 +490,13 @@ static void fsl_ddr_init_csrows(struct mem_ctl_info *mci)
}
}
+static void fsl_mc_edac_free(void *data)
+{
+ struct mem_ctl_info *mci = data;
+
+ edac_mc_free(mci);
+}
+
int fsl_mc_err_probe(struct platform_device *op)
{
struct mem_ctl_info *mci;
@@ -500,9 +507,6 @@ int fsl_mc_err_probe(struct platform_device *op)
u32 sdram_ctl;
int res;
- if (!devres_open_group(&op->dev, fsl_mc_err_probe, GFP_KERNEL))
- return -ENOMEM;
-
layers[0].type = EDAC_MC_LAYER_CHIP_SELECT;
layers[0].size = 4;
layers[0].is_virt_csrow = true;
@@ -511,10 +515,17 @@ int fsl_mc_err_probe(struct platform_device *op)
layers[1].is_virt_csrow = false;
mci = edac_mc_alloc(edac_mc_idx, ARRAY_SIZE(layers), layers,
sizeof(*pdata));
- if (!mci) {
- devres_release_group(&op->dev, fsl_mc_err_probe);
+ if (!mci)
return -ENOMEM;
- }
+
+ /*
+ * Manage mci lifetime via devres so it is freed only after the
+ * devm-requested IRQ is released, avoiding a use-after-free of mci
+ * (and its pdata) in the shared interrupt handler during removal.
+ */
+ res = devm_add_action_or_reset(&op->dev, fsl_mc_edac_free, mci);
+ if (res)
+ return res;
pdata = mci->pvt_info;
pdata->name = "fsl_mc_err";
@@ -558,10 +569,8 @@ int fsl_mc_err_probe(struct platform_device *op)
if (pdata->flag == TYPE_IMX9) {
pdata->inject_vbase = devm_platform_ioremap_resource_byname(op, "inject");
- if (IS_ERR(pdata->inject_vbase)) {
- res = -ENOMEM;
- goto err;
- }
+ if (IS_ERR(pdata->inject_vbase))
+ return -ENOMEM;
}
if (pdata->flag == TYPE_IMX9) {
@@ -575,8 +584,7 @@ int fsl_mc_err_probe(struct platform_device *op)
if ((sdram_ctl & ecc_en_mask) != ecc_en_mask) {
/* no ECC */
pr_warn("%s: No ECC DIMMs discovered\n", __func__);
- res = -ENODEV;
- goto err;
+ return -ENODEV;
}
edac_dbg(3, "init mci\n");
@@ -639,7 +647,6 @@ int fsl_mc_err_probe(struct platform_device *op)
pdata->irq);
}
- devres_remove_group(&op->dev, fsl_mc_err_probe);
edac_dbg(3, "success\n");
pr_info(EDAC_MOD_STR " MC err registered\n");
@@ -652,8 +659,6 @@ int fsl_mc_err_probe(struct platform_device *op)
ddr_out32(pdata, FSL_MC_ERR_DISABLE,
pdata->orig_ddr_err_disable);
ddr_out32(pdata, FSL_MC_ERR_SBE, pdata->orig_ddr_err_sbe);
- devres_release_group(&op->dev, fsl_mc_err_probe);
- edac_mc_free(mci);
return res;
}
@@ -674,5 +679,4 @@ void fsl_mc_err_remove(struct platform_device *op)
edac_mc_del_mc(&op->dev);
- edac_mc_free(mci);
}
--
2.55.0
next prev parent reply other threads:[~2026-07-19 19:40 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-19 19:40 [PATCH 0/2] EDAC: fsl_ddr: probe failure and remove lifetime fixes Rosen Penev
2026-07-19 19:40 ` [PATCH 1/2] EDAC: fsl_ddr: restore MC error registers on probe failure Rosen Penev
2026-07-19 19:51 ` sashiko-bot
2026-07-19 19:40 ` Rosen Penev [this message]
2026-07-19 19:51 ` [PATCH 2/2] EDAC: fsl_ddr: manage mci lifetime via devres to fix remove UAF sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260719194009.117532-3-rosenp@gmail.com \
--to=rosenp@gmail.com \
--cc=Frank.Li@nxp.com \
--cc=bp@alien8.de \
--cc=imx@lists.linux.dev \
--cc=justinstitt@google.com \
--cc=linux-edac@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=llvm@lists.linux.dev \
--cc=morbo@google.com \
--cc=nathan@kernel.org \
--cc=ndesaulniers@google.com \
--cc=tony.luck@intel.com \
--cc=york.sun@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.