[PATCH 8/9] EDAC/versalnet: Fix use-after-free in remove_one_mc()

From: Shubhrajyoti Datta

Date: Fri Jul 24 2026 - 13:32:29 EST


device_unregister() drops the last reference on the device and invokes
versal_edac_release() which calls kfree(dev). The subsequent call to
edac_mc_del_mc(mci->pdev) then dereferences the freed pointer.

Fix by saving the device pointer, calling edac_mc_del_mc() and
edac_mc_free() first, then device_unregister() last so the device
is freed only after all users are done with it.

Fixes: 62a9fc50e8d9 ("EDAC/versalnet: Refactor memory controller initialization and cleanup")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@xxxxxxx>
---

drivers/edac/versalnet_edac.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/edac/versalnet_edac.c b/drivers/edac/versalnet_edac.c
index baca90f44c58..ba295714d972 100644
--- a/drivers/edac/versalnet_edac.c
+++ b/drivers/edac/versalnet_edac.c
@@ -763,14 +763,16 @@ static void versal_edac_release(struct device *dev)
static void remove_one_mc(struct mc_priv *priv, int i)
{
struct mem_ctl_info *mci;
+ struct device *dev;

mci = priv->mci[i];
if (!mci)
return;

- device_unregister(mci->pdev);
- edac_mc_del_mc(mci->pdev);
+ dev = mci->pdev;
+ edac_mc_del_mc(dev);
edac_mc_free(mci);
+ device_unregister(dev);
}

static int init_one_mc(struct mc_priv *priv, int i)
--
2.34.1