Patch "platform/x86: wmi: Fix driver->notify() vs ->probe() race" has been added to the 5.15-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    platform/x86: wmi: Fix driver->notify() vs ->probe() race

to the 5.15-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     platform-x86-wmi-fix-driver-notify-vs-probe-race.patch
and it can be found in the queue-5.15 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4fb1d32679362fbe42c6b51cc7b97aca3c883712
Author: Hans de Goede <hdegoede@xxxxxxxxxx>
Date:   Sun Nov 28 20:00:28 2021 +0100

    platform/x86: wmi: Fix driver->notify() vs ->probe() race
    
    [ Upstream commit 9918878676a5f9e99b98679f04b9e6c0f5426b0a ]
    
    The driver core sets struct device->driver before calling out
    to the bus' probe() method, this leaves a window where an ACPI
    notify may happen on the WMI object before the driver's
    probe() method has completed running, causing e.g. the
    driver's notify() callback to get called with drvdata
    not yet being set leading to a NULL pointer deref.
    
    At a check for this to the WMI core, ensuring that the notify()
    callback is not called before the driver is ready.
    
    Fixes: 1686f5444546 ("platform/x86: wmi: Incorporate acpi_install_notify_handler")
    Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>
    Signed-off-by: Hans de Goede <hdegoede@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20211128190031.405620-2-hdegoede@xxxxxxxxxx
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index a00b72ace6d2..c4f917d45b51 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -53,6 +53,7 @@ struct guid_block {
 
 enum {	/* wmi_block flags */
 	WMI_READ_TAKES_NO_ARGS,
+	WMI_PROBED,
 };
 
 struct wmi_block {
@@ -980,6 +981,7 @@ static int wmi_dev_probe(struct device *dev)
 		}
 	}
 
+	set_bit(WMI_PROBED, &wblock->flags);
 	return 0;
 
 probe_misc_failure:
@@ -997,6 +999,8 @@ static void wmi_dev_remove(struct device *dev)
 	struct wmi_block *wblock = dev_to_wblock(dev);
 	struct wmi_driver *wdriver = drv_to_wdrv(dev->driver);
 
+	clear_bit(WMI_PROBED, &wblock->flags);
+
 	if (wdriver->filter_callback) {
 		misc_deregister(&wblock->char_dev);
 		kfree(wblock->char_dev.name);
@@ -1299,7 +1303,7 @@ static void acpi_wmi_notify_handler(acpi_handle handle, u32 event,
 		return;
 
 	/* If a driver is bound, then notify the driver. */
-	if (wblock->dev.dev.driver) {
+	if (test_bit(WMI_PROBED, &wblock->flags) && wblock->dev.dev.driver) {
 		struct wmi_driver *driver = drv_to_wdrv(wblock->dev.dev.driver);
 		struct acpi_object_list input;
 		union acpi_object params[1];



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux