Skip to content

Commit 13d201b

Browse files
Danilo Krummrichgregkh
authored andcommitted
platform/wmi: use generic driver_override infrastructure
[ Upstream commit 8a700b1 ] When a driver is probed through __driver_attach(), the bus' match() callback is called without the device lock held, thus accessing the driver_override field without a lock, which can cause a UAF. Fix this by using the driver-core driver_override infrastructure taking care of proper locking internally. Note that calling match() from __driver_attach() without the device lock held is intentional. [1] Link: https://lore.kernel.org/driver-core/DGRGTIRHA62X.3RY09D9SOK77P@kernel.org/ [1] Reported-by: Gui-Dong Han <hanguidong02@gmail.com> Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789 Fixes: 12046f8 ("platform/x86: wmi: Add driver_override support") Reviewed-by: Armin Wolf <W_Armin@gmx.de> Acked-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://patch.msgid.link/20260324005919.2408620-7-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent dfe950d commit 13d201b

2 files changed

Lines changed: 5 additions & 35 deletions

File tree

drivers/platform/x86/wmi.c

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -696,39 +696,11 @@ static ssize_t expensive_show(struct device *dev,
696696
}
697697
static DEVICE_ATTR_RO(expensive);
698698

699-
static ssize_t driver_override_show(struct device *dev, struct device_attribute *attr,
700-
char *buf)
701-
{
702-
struct wmi_device *wdev = to_wmi_device(dev);
703-
ssize_t ret;
704-
705-
device_lock(dev);
706-
ret = sysfs_emit(buf, "%s\n", wdev->driver_override);
707-
device_unlock(dev);
708-
709-
return ret;
710-
}
711-
712-
static ssize_t driver_override_store(struct device *dev, struct device_attribute *attr,
713-
const char *buf, size_t count)
714-
{
715-
struct wmi_device *wdev = to_wmi_device(dev);
716-
int ret;
717-
718-
ret = driver_set_override(dev, &wdev->driver_override, buf, count);
719-
if (ret < 0)
720-
return ret;
721-
722-
return count;
723-
}
724-
static DEVICE_ATTR_RW(driver_override);
725-
726699
static struct attribute *wmi_attrs[] = {
727700
&dev_attr_modalias.attr,
728701
&dev_attr_guid.attr,
729702
&dev_attr_instance_count.attr,
730703
&dev_attr_expensive.attr,
731-
&dev_attr_driver_override.attr,
732704
NULL
733705
};
734706
ATTRIBUTE_GROUPS(wmi);
@@ -797,7 +769,6 @@ static void wmi_dev_release(struct device *dev)
797769
{
798770
struct wmi_block *wblock = dev_to_wblock(dev);
799771

800-
kfree(wblock->dev.driver_override);
801772
kfree(wblock);
802773
}
803774

@@ -806,10 +777,12 @@ static int wmi_dev_match(struct device *dev, const struct device_driver *driver)
806777
const struct wmi_driver *wmi_driver = drv_to_wdrv(driver);
807778
struct wmi_block *wblock = dev_to_wblock(dev);
808779
const struct wmi_device_id *id = wmi_driver->id_table;
780+
int ret;
809781

810782
/* When driver_override is set, only bind to the matching driver */
811-
if (wblock->dev.driver_override)
812-
return !strcmp(wblock->dev.driver_override, driver->name);
783+
ret = device_match_driver_override(dev, driver);
784+
if (ret >= 0)
785+
return ret;
813786

814787
if (id == NULL)
815788
return 0;
@@ -891,6 +864,7 @@ static struct class wmi_bus_class = {
891864
static const struct bus_type wmi_bus_type = {
892865
.name = "wmi",
893866
.dev_groups = wmi_groups,
867+
.driver_override = true,
894868
.match = wmi_dev_match,
895869
.uevent = wmi_dev_uevent,
896870
.probe = wmi_dev_probe,

include/linux/wmi.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,12 @@
1616
* struct wmi_device - WMI device structure
1717
* @dev: Device associated with this WMI device
1818
* @setable: True for devices implementing the Set Control Method
19-
* @driver_override: Driver name to force a match; do not set directly,
20-
* because core frees it; use driver_set_override() to
21-
* set or clear it.
2219
*
2320
* This represents WMI devices discovered by the WMI driver core.
2421
*/
2522
struct wmi_device {
2623
struct device dev;
2724
bool setable;
28-
const char *driver_override;
2925
};
3026

3127
/**

0 commit comments

Comments
 (0)