Commit 5e87c475 authored by Prarit Bhargava's avatar Prarit Bhargava Committed by Greg Kroah-Hartman

acpi/nfit: Fix memory corruption/Unregister mce decoder on failure

commit 7e700d2c upstream.

nfit_init() calls nfit_mce_register() on module load.  When the module
load fails the nfit mce decoder is not unregistered.  The module's
memory is freed leaving the decoder chain referencing junk.  This will
cause panics as future registrations will reference the free'd memory.

Unregister the nfit mce decoder on module init failure.

[v2]: register and then unregister mce handler to avoid losing mce events
[v3]: also cleanup nfit workqueue

Fixes: 6839a6d9 ("nfit: do an ARS scrub on hitting a latent media error")
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
Cc: Vishal Verma <vishal.l.verma@intel.com>
Cc: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
Cc: Linda Knippers <linda.knippers@hpe.com>
Cc: lszubowi@redhat.com
Acked-by: default avatarJeff Moyer <jmoyer@redhat.com>
Signed-off-by: default avatarPrarit Bhargava <prarit@redhat.com>
Reviewed-by: default avatarVishal Verma <vishal.l.verma@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 054728d3
...@@ -3043,6 +3043,8 @@ static struct acpi_driver acpi_nfit_driver = { ...@@ -3043,6 +3043,8 @@ static struct acpi_driver acpi_nfit_driver = {
static __init int nfit_init(void) static __init int nfit_init(void)
{ {
int ret;
BUILD_BUG_ON(sizeof(struct acpi_table_nfit) != 40); BUILD_BUG_ON(sizeof(struct acpi_table_nfit) != 40);
BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address) != 56); BUILD_BUG_ON(sizeof(struct acpi_nfit_system_address) != 56);
BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map) != 48); BUILD_BUG_ON(sizeof(struct acpi_nfit_memory_map) != 48);
...@@ -3070,8 +3072,14 @@ static __init int nfit_init(void) ...@@ -3070,8 +3072,14 @@ static __init int nfit_init(void)
return -ENOMEM; return -ENOMEM;
nfit_mce_register(); nfit_mce_register();
ret = acpi_bus_register_driver(&acpi_nfit_driver);
if (ret) {
nfit_mce_unregister();
destroy_workqueue(nfit_wq);
}
return ret;
return acpi_bus_register_driver(&acpi_nfit_driver);
} }
static __exit void nfit_exit(void) static __exit void nfit_exit(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment