]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
EDAC/ghes: Fix NULL pointer dereference in ghes_edac_register()
authorShiju Jose <shiju.jose@huawei.com>
Thu, 27 Aug 2020 14:04:50 +0000 (15:04 +0100)
committerBorislav Petkov <bp@suse.de>
Thu, 27 Aug 2020 16:04:07 +0000 (18:04 +0200)
After

  b9cae27728d1 ("EDAC/ghes: Scan the system once on driver init")

and with CONFIG_DEBUG_TEST_DRIVER_REMOVE enabled, ghes_hw.dimms becomes
a NULL pointer after the second ->probe() (aka ghes_edac_register())
which the config option causes to be called.

This happens because the static variable which holds down whether
the system has been scanned already, doesn't get reset in
ghes_edac_unregister(). Then, on the second probe, ghes_scan_system()
doesn't get to enumerate the DIMMs, leading to ghes_hw.dimms remaining
NULL.

Clear the variable and rename it to something more descriptive so that a
second probe succeeds.

 [ bp: Rewrite commit message. ]

Fixes: b9cae27728d1 ("EDAC/ghes: Scan the system once on driver init")
Suggested-by: Borislav Petkov <bp@suse.de>
Signed-off-by: Shiju Jose <shiju.jose@huawei.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20200827140450.1620-1-shiju.jose@huawei.com
drivers/edac/ghes_edac.c

index da60c29468a7cf48575ed1d8000963732ceb5728..54ebc8afc6b1bb2de7c4aecb94734816c38651f0 100644 (file)
@@ -55,6 +55,8 @@ static DEFINE_SPINLOCK(ghes_lock);
 static bool __read_mostly force_load;
 module_param(force_load, bool, 0);
 
+static bool system_scanned;
+
 /* Memory Device - Type 17 of SMBIOS spec */
 struct memdev_dmi_entry {
        u8 type;
@@ -225,14 +227,12 @@ static void enumerate_dimms(const struct dmi_header *dh, void *arg)
 
 static void ghes_scan_system(void)
 {
-       static bool scanned;
-
-       if (scanned)
+       if (system_scanned)
                return;
 
        dmi_walk(enumerate_dimms, &ghes_hw);
 
-       scanned = true;
+       system_scanned = true;
 }
 
 void ghes_edac_report_mem_error(int sev, struct cper_sec_mem_err *mem_err)
@@ -631,6 +631,8 @@ void ghes_edac_unregister(struct ghes *ghes)
 
        mutex_lock(&ghes_reg_mutex);
 
+       system_scanned = false;
+
        if (!refcount_dec_and_test(&ghes_refcount))
                goto unlock;