From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9DD5F2EEE9B for ; Sun, 19 Jul 2026 19:40:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.49 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784490022; cv=none; b=A2W8y4r4F7qYFjeisPVsn1HUl9pMuXVj+wHbJfRPEe5QmPLKQ/mplPlXTFK2X2QXgKlNqoh/UUdG3mGScsEn0saHWelKvzEJXX62BMl2MQZtpRQ6gkO9Hwp9lgb6N7ZXw31eifumCWMSNsHgIFrgNfacaf9AiYVXyV7EU0yFQnQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784490022; c=relaxed/simple; bh=TLJtucb+fMTnZkK3MG1MYEdha1u6aPFM1hXEkh/SJAc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=BFxvUb8iI8vnbYtgTdpAZXXobcob0lz1bunf3UnWuUEgEG/Il091CBIxJ75H1ASDofzi0HqtGNfvC0HjRJ/hwsONhe2BaY00zWkp2sa2VNNuvTZOTMBlBJaIP7azqAmOTmuGjGxtHC0UzIYYfoirg5ZcmzXDxKOv7EPpcf4Pf3w= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=DwCPQnG6; arc=none smtp.client-ip=209.85.216.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DwCPQnG6" Received: by mail-pj1-f49.google.com with SMTP id 98e67ed59e1d1-38125cebfdaso6995722a91.1 for ; Sun, 19 Jul 2026 12:40:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784490020; x=1785094820; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=JHDTeZIldDDYJIkvsl14Ioncr+9aGn9+y+1u1DznXfQ=; b=DwCPQnG6CtKfQ5VhtW2rdF6WiQuv0YWCJNt11UzsqCXi09TvmjkPXxdKIl5ENu5Sp0 q5ypT5Vev04wTuksDHZcbFkh5C3AvHJ0H93pG16Uasj1DC2wDPeXjz5pcScX31mfrfbo vgAw0r+DwKaFNuAXTRwTKKfm0L9oFXoj3CFeqIsrzGFZ4E98JquYPPDGVBo04Ni4jcr3 JU/5qRTvJ0VHt4GTDLptcDLz1lJ9B7FWsHHGQRELHnOmERHLDxmBZaEz8Gyn2i8IJI5O 3PiPvKN+WwjW9gaTddhN8kBJve8gaziVUM4gDby83FUd8ST0J4H7mKOl0noVO7yVzmyN Py2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784490020; x=1785094820; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=JHDTeZIldDDYJIkvsl14Ioncr+9aGn9+y+1u1DznXfQ=; b=SI4fnRIb79dXjMmtVQSSkxS9K/9gyifLuNqi04MOp8jsgxdAxX7vbcjn0bEislJ1Ls Pi3bBp7wbFoOkJ9u1xrghPBzUTjLnC0Pe13aGbJ1+aEsNFoSZoaVeWxEtfI69VIYyWUC UcJ6t3QnRBsNT808ecsV1vQyKwvTqUUgYBBndQXs35pXKKQpe9BfXAB9VclwjVw/WTDw +jEVrmwnSfis+WaKhOjC5Rm1hV7/yDQFyrtR53H3vrpIoCowmv+H2utReim6xLb+WSFZ 5CXueWohRQhCwhYutVDqHH8/oWt1MIB9N/afCQXc5TjAffQUr+j8+mPLZ8TMem+i1Stt AIEQ== X-Forwarded-Encrypted: i=1; AHgh+Ro/aIo0oblncs8eN6SUmJzbtTrd8cByVsJBSuh8H8atd2jUfKSY7eoDhxMSHDZDw49R94oPyCSICzm6VZ0=@vger.kernel.org X-Gm-Message-State: AOJu0YxfUNnxOCtB+FWgPpPGXn5AOzQjy6lydvkFoACg+2wkWYAWd09F uirMnO/0ZwglsOwjJfSrWKlEvDwQQehw+FEcfmucn7aiiYGcVNU1N5CE X-Gm-Gg: AfdE7cnZY8+BOw0Sxuml3sCf5xue0ISNUBPRWGkzQPxcB8iHiFZsUEluZwxrKc07SaD 7u0/6ztftQhXCxTepZRDmNp+ngOpNL2nlh+LBTg5stOQg0MhcqQErtmg4CxygfB8EKZ3IYWWQ60 tD7/3M2kCuMK8YlF1HSLiL3okOOHl7c7q3LeorUFvW6ixtLrDM3ZzRBho4o9YIdYuUwomXHtZVy ZzHbQUns/qDg7oz9frxI1HegF+2FBvPAyWKn6F27Gb5UBOYFZk4FAbeuXblOcdS4IikmZKgE0Rl GiW0hkn8qS21JW0hAWP0D4I1z5N2okwg2/dtu+1LUVRoe1S7PX1jLOKSMUtKxPM77e+couNxGtB TlLsjB1PaYjgGQQVtTeaZfM61gF6HKcgyo8XO9Q+K/D/tui8nkiDs1m44/3dkwn1BWH6/8dJsUZ x3H4FJUp6FAB1TNr2PVyaPUk3hav1S++1UioeIG5/ckjg87jZrbHdkJYm69hWTQFg2wMBz4AXGJ h0moS4rs3z5HL9Hn2fpv2z9KYKY0l1ZeVwcHi6/3MAHCdv04fUvhos= X-Received: by 2002:a17:90b:2f0c:b0:38e:49c0:75a7 with SMTP id 98e67ed59e1d1-38e4b431074mr12281543a91.8.1784490019784; Sun, 19 Jul 2026 12:40:19 -0700 (PDT) Received: from ryzen.lan ([2601:644:8000:7a86::e35]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-38e3a0fb993sm6308126a91.15.2026.07.19.12.40.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jul 2026 12:40:17 -0700 (PDT) From: Rosen Penev To: linux-edac@vger.kernel.org Cc: Frank Li , Borislav Petkov , Tony Luck , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , York Sun , 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 Message-ID: <20260719194009.117532-3-rosenp@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260719194009.117532-1-rosenp@gmail.com> References: <20260719194009.117532-1-rosenp@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 --- 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