|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 08/12] vdpa: use generic driver_override infrastructure
On Tue, Mar 24, 2026 at 2:00 AM Danilo Krummrich <dakr@xxxxxxxxxx> 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: 539fec78edb4 ("vdpa: add driver_override support") > Signed-off-by: Danilo Krummrich <dakr@xxxxxxxxxx> > --- > drivers/vdpa/vdpa.c | 48 +++++--------------------------------------- > include/linux/vdpa.h | 4 ---- > 2 files changed, 5 insertions(+), 47 deletions(-) > Consolidate this logic is great, thanks! > diff --git a/drivers/vdpa/vdpa.c b/drivers/vdpa/vdpa.c > index 34874beb0152..caf0ee5d6856 100644 > --- a/drivers/vdpa/vdpa.c > +++ b/drivers/vdpa/vdpa.c > @@ -67,57 +67,20 @@ static void vdpa_dev_remove(struct device *d) > > static int vdpa_dev_match(struct device *dev, const struct device_driver > *drv) > { > - struct vdpa_device *vdev = dev_to_vdpa(dev); > + int ret; > > /* Check override first, and if set, only use the named driver */ > - if (vdev->driver_override) > - return strcmp(vdev->driver_override, drv->name) == 0; > + ret = device_match_driver_override(dev, drv); > + if (ret >= 0) > + return ret; > > /* Currently devices must be supported by all vDPA bus drivers */ > return 1; Nit: Maybe all of this can be replaced by abs(device_match_driver_override(dev,drv))? Or maybe we're putting too much in the same line. Either way, Acked-by: Eugenio Pérez <eperezma@xxxxxxxxxx> Thanks! > } > > -static ssize_t driver_override_store(struct device *dev, > - struct device_attribute *attr, > - const char *buf, size_t count) > -{ > - struct vdpa_device *vdev = dev_to_vdpa(dev); > - int ret; > - > - ret = driver_set_override(dev, &vdev->driver_override, buf, count); > - if (ret) > - return ret; > - > - return count; > -} > - > -static ssize_t driver_override_show(struct device *dev, > - struct device_attribute *attr, char *buf) > -{ > - struct vdpa_device *vdev = dev_to_vdpa(dev); > - ssize_t len; > - > - device_lock(dev); > - len = sysfs_emit(buf, "%s\n", vdev->driver_override); > - device_unlock(dev); > - > - return len; > -} > -static DEVICE_ATTR_RW(driver_override); > - > -static struct attribute *vdpa_dev_attrs[] = { > - &dev_attr_driver_override.attr, > - NULL, > -}; > - > -static const struct attribute_group vdpa_dev_group = { > - .attrs = vdpa_dev_attrs, > -}; > -__ATTRIBUTE_GROUPS(vdpa_dev); > - > static const struct bus_type vdpa_bus = { > .name = "vdpa", > - .dev_groups = vdpa_dev_groups, > + .driver_override = true, > .match = vdpa_dev_match, > .probe = vdpa_dev_probe, > .remove = vdpa_dev_remove, > @@ -132,7 +95,6 @@ static void vdpa_release_dev(struct device *d) > ops->free(vdev); > > ida_free(&vdpa_index_ida, vdev->index); > - kfree(vdev->driver_override); > kfree(vdev); > } > > diff --git a/include/linux/vdpa.h b/include/linux/vdpa.h > index 2bfe3baa63f4..782c42d25db1 100644 > --- a/include/linux/vdpa.h > +++ b/include/linux/vdpa.h > @@ -72,9 +72,6 @@ struct vdpa_mgmt_dev; > * struct vdpa_device - representation of a vDPA device > * @dev: underlying device > * @vmap: the metadata passed to upper layer to be used for mapping > - * @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. > * @config: the configuration ops for this device. > * @map: the map ops for this device > * @cf_lock: Protects get and set access to configuration layout. > @@ -90,7 +87,6 @@ struct vdpa_mgmt_dev; > struct vdpa_device { > struct device dev; > union virtio_map vmap; > - const char *driver_override; > const struct vdpa_config_ops *config; > const struct virtio_map_ops *map; > struct rw_semaphore cf_lock; /* Protects get/set config */ > -- > 2.53.0 >
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |