Received: by 2002:a25:d7c1:0:0:0:0:0 with SMTP id o184csp2787295ybg; Mon, 28 Oct 2019 02:21:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqyq9+8BcgSpZoLPtE94vsPF6IYWZib6YMpRwyMKUK4z6P5AoCxjIEAYiYExUucJY2f1GVuZ X-Received: by 2002:a05:6402:19ae:: with SMTP id o14mr14067742edz.108.1572254494463; Mon, 28 Oct 2019 02:21:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1572254494; cv=none; d=google.com; s=arc-20160816; b=EMhQs46siKdaG9TD/QOa0Izm7AC6qkTQcvmu4UId/TNuHJ88QpRZ85OorVoNYwLDxo aeEsFhfsMkpeLYCk8x9PCVlutTQoQNxsyNuCyRbpAXAcHdi9sNqjhGYIXbXUhXfhf0N5 e5ecV/RLVM6pbTG4iYNi2kbdlykGy8FbgiBLBGDwLtvdPjALNpA4e/6bKZcKM9IW0Kzd 9EJknm5ec55knxV1unVNsxgNobnAMR/J+3rufBPEeVAJBw04ObEqtOISfelg0yG+ZW/a 20I3htcw2vf0o9K1R1hwxwdJs6sYYkd0VSDz4LxS6fCcC9J7QwznqojKIzKy4w84YrCb K8wg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=CoTYLXk4xcFfjxQul0z4YJ63hCgrOo8niE4So3NxYWo=; b=ODL6CwWQEoK3SOfebAGtI60b5GpJkQ7FqmkmFOz82QWPDetvv+RokKI351RHUGIzLq Y4wHReplUtxNGw0EDu9AwpO087UqPvk18UjXmizJCS65V/F329kdHrVMI8j2ntkDaddh NxElTYGhvORSaPSe1/+iF8dsL+cVIjke49kJaPLOMAZXgBxOOef5OuvClhmxHY9aQYKB oUwOJQydiTLocTrIVyzEm5actHbbKDMFfZC3HXZQKdknteArUBP2T5VTFcfg16gaUtps j9JKhInGVHBnzCcC242NHgCDk5f95Y8nLRz93SAry/rXeWozqsfDyhaRcZ7IatkQxCc6 /wsw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ChvKMzfB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c19si5846310ejs.171.2019.10.28.02.21.11; Mon, 28 Oct 2019 02:21:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ChvKMzfB; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732542AbfJ0VYe (ORCPT + 99 others); Sun, 27 Oct 2019 17:24:34 -0400 Received: from mail.kernel.org ([198.145.29.99]:46158 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732534AbfJ0VYc (ORCPT ); Sun, 27 Oct 2019 17:24:32 -0400 Received: from localhost (100.50.158.77.rev.sfr.net [77.158.50.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id B8BCC21783; Sun, 27 Oct 2019 21:24:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1572211471; bh=+9jZZGeI7w6970cSzL2GnY+5H/WDdvxEd0GZbvc3oaQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ChvKMzfBeWdcS63/aRH0G2THLmFDINW5sFUObdsrITpuxpvTpA6GizIBeVnUN3ltU SUf9Y1JNrWKzctjxyVrDC8E5NxVwbd6xmp/tWvcoKZlfyTSXpX3eYws8qko41HiBU7 i6h0hQKyPsEy5WLe2H8cKraWAuKIN/1XJClLSS8c= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, John Garry , James Morse , Borislav Petkov , linux-edac , Mauro Carvalho Chehab , Robert Richter , Tony Luck Subject: [PATCH 5.3 162/197] EDAC/ghes: Fix Use after free in ghes_edac remove path Date: Sun, 27 Oct 2019 22:01:20 +0100 Message-Id: <20191027203402.547589321@linuxfoundation.org> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191027203351.684916567@linuxfoundation.org> References: <20191027203351.684916567@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: James Morse commit 1e72e673b9d102ff2e8333e74b3308d012ddf75b upstream. ghes_edac models a single logical memory controller, and uses a global ghes_init variable to ensure only the first ghes_edac_register() will do anything. ghes_edac is registered the first time a GHES entry in the HEST is probed. There may be multiple entries, so subsequent attempts to register ghes_edac are silently ignored as the work has already been done. When a GHES entry is unregistered, it calls ghes_edac_unregister(), which free()s the memory behind the global variables in ghes_edac. But there may be multiple GHES entries, the next call to ghes_edac_unregister() will dereference the free()d memory, and attempt to free it a second time. This may also be triggered on a platform with one GHES entry, if the driver is unbound/re-bound and unbound. The re-bind step will do nothing because of ghes_init, the second unbind will then do the same work as the first. Doing the unregister work on the first call is unsafe, as another CPU may be processing a notification in ghes_edac_report_mem_error(), using the memory we are about to free. ghes_init is already half of the reference counting. We only need to do the register work for the first call, and the unregister work for the last. Add the unregister check. This means we no longer free ghes_edac's memory while there are GHES entries that may receive a notification. This was detected by KASAN and DEBUG_TEST_DRIVER_REMOVE. [ bp: merge into a single patch. ] Fixes: 0fe5f281f749 ("EDAC, ghes: Model a single, logical memory controller") Reported-by: John Garry Signed-off-by: James Morse Signed-off-by: Borislav Petkov Cc: linux-edac Cc: Mauro Carvalho Chehab Cc: Robert Richter Cc: Tony Luck Cc: Link: https://lkml.kernel.org/r/20191014171919.85044-2-james.morse@arm.com Link: https://lkml.kernel.org/r/304df85b-8b56-b77e-1a11-aa23769f2e7c@huawei.com Signed-off-by: Greg Kroah-Hartman --- drivers/edac/ghes_edac.c | 4 ++++ 1 file changed, 4 insertions(+) --- a/drivers/edac/ghes_edac.c +++ b/drivers/edac/ghes_edac.c @@ -553,7 +553,11 @@ void ghes_edac_unregister(struct ghes *g if (!ghes_pvt) return; + if (atomic_dec_return(&ghes_init)) + return; + mci = ghes_pvt->mci; + ghes_pvt = NULL; edac_mc_del_mc(mci->pdev); edac_mc_free(mci); }