|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 06/12] platform/wmi: use generic driver_override infrastructure
On Tue, 24 Mar 2026, Danilo Krummrich wrote: > 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@xxxxxxxxxx/ [1] > Reported-by: Gui-Dong Han <hanguidong02@xxxxxxxxx> > Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220789 > Fixes: 12046f8c77e0 ("platform/x86: wmi: Add driver_override support") > Signed-off-by: Danilo Krummrich <dakr@xxxxxxxxxx> > --- > drivers/platform/wmi/core.c | 36 +++++------------------------------- > include/linux/wmi.h | 4 ---- > 2 files changed, 5 insertions(+), 35 deletions(-) > > diff --git a/drivers/platform/wmi/core.c b/drivers/platform/wmi/core.c > index b8e6b9a421c6..750e3619724e 100644 > --- a/drivers/platform/wmi/core.c > +++ b/drivers/platform/wmi/core.c > @@ -842,39 +842,11 @@ static ssize_t expensive_show(struct device *dev, > } > static DEVICE_ATTR_RO(expensive); > > -static ssize_t driver_override_show(struct device *dev, struct > device_attribute *attr, > - char *buf) > -{ > - struct wmi_device *wdev = to_wmi_device(dev); > - ssize_t ret; > - > - device_lock(dev); > - ret = sysfs_emit(buf, "%s\n", wdev->driver_override); > - device_unlock(dev); > - > - return ret; > -} > - > -static ssize_t driver_override_store(struct device *dev, struct > device_attribute *attr, > - const char *buf, size_t count) > -{ > - struct wmi_device *wdev = to_wmi_device(dev); > - int ret; > - > - ret = driver_set_override(dev, &wdev->driver_override, buf, count); > - if (ret < 0) > - return ret; > - > - return count; > -} > -static DEVICE_ATTR_RW(driver_override); > - > static struct attribute *wmi_attrs[] = { > &dev_attr_modalias.attr, > &dev_attr_guid.attr, > &dev_attr_instance_count.attr, > &dev_attr_expensive.attr, > - &dev_attr_driver_override.attr, > NULL > }; > ATTRIBUTE_GROUPS(wmi); > @@ -943,7 +915,6 @@ static void wmi_dev_release(struct device *dev) > { > struct wmi_block *wblock = dev_to_wblock(dev); > > - kfree(wblock->dev.driver_override); > kfree(wblock); > } > > @@ -952,10 +923,12 @@ static int wmi_dev_match(struct device *dev, const > struct device_driver *driver) > const struct wmi_driver *wmi_driver = to_wmi_driver(driver); > struct wmi_block *wblock = dev_to_wblock(dev); > const struct wmi_device_id *id = wmi_driver->id_table; > + int ret; > > /* When driver_override is set, only bind to the matching driver */ > - if (wblock->dev.driver_override) > - return !strcmp(wblock->dev.driver_override, driver->name); > + ret = device_match_driver_override(dev, driver); > + if (ret >= 0) > + return ret; > > if (id == NULL) > return 0; > @@ -1076,6 +1049,7 @@ static struct class wmi_bus_class = { > static const struct bus_type wmi_bus_type = { > .name = "wmi", > .dev_groups = wmi_groups, > + .driver_override = true, > .match = wmi_dev_match, > .uevent = wmi_dev_uevent, > .probe = wmi_dev_probe, > diff --git a/include/linux/wmi.h b/include/linux/wmi.h > index 75cb0c7cfe57..14fb644e1701 100644 > --- a/include/linux/wmi.h > +++ b/include/linux/wmi.h > @@ -18,16 +18,12 @@ > * struct wmi_device - WMI device structure > * @dev: Device associated with this WMI device > * @setable: True for devices implementing the Set Control Method > - * @driver_override: Driver name to force a match; do not set directly, > - * because core frees it; use driver_set_override() to > - * set or clear it. > * > * This represents WMI devices discovered by the WMI driver core. > */ > struct wmi_device { > struct device dev; > bool setable; > - const char *driver_override; > }; > > /** > Hi, I tried applying this to platform-drivers tree but it failed to compile so I ended up dropping the changed. -- i.
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |