[lvc-project] [PATCH] most: core, usb: fix generic device management

Fedor Pchelkin pchelkin at ispras.ru
Tue Jul 15 18:34:07 MSK 2025


Думаю, в этом патче должны быть заинтересованы подписчики
linux-usb at vger.kernel.org. Этот список не добавлен в адресаты.

Также возможно лучше добавить в копию адресатов из обсуждения
https://lore.kernel.org/linux-usb/e8310fd2-caa7-4a78-8ff1-2bc2d07d74c1@suse.com/

On Mon, 16. Jun 19:53, Dmitry Antipov wrote:
> Syzkaller reports [1, 2] refcount and use-after-free errors for
> the generic 'struct device' data used here and there. An overall
> usage of the generic device is somewhat confusing because the
> same device instance is shared between 'struct most_dev' and
> 'struct most_interface' instances and as a parent of the device
> embedded into 'struct most_dci_obj' instance pointed from the
> former. This patch hopefully fixes both of the known issues
> assumes the following:
> 
> 1. Direct 'mdev->iface.dev = &mdev->dev' assignment performed in
>    'hdm_probe()' is wrong and 'get_device()' should be used to
>    not break an internal reference counting.
> 2. To use 'get_device()' in the code above, an underlying device
>    should be properly initialized with 'device_initialize()'. So
>    'most_register_interface()' should use 'device_add()' rather
>    than 'device_register()'.
> 3. In 'hdm_disconnect()', 'put_device(&mdev->dci->dev)' is wrong
>    because it's done from 'device_unregister(&mdev->dci->dev)'
>    called from the above.
> 
> [1] https://syzkaller.appspot.com/bug?extid=d175ca7205b4f18390b1
> [2] https://syzkaller.appspot.com/bug?extid=916742d5d24f6c254761
> 

при взаимодействии с Центром требуется

Found by Linux Verification Center ...


Тег Fixes очень желателен, а лучше ещё вдобавок и
Cc: stable at vger.kernel.org

> Signed-off-by: Dmitry Antipov <dmantipov at yandex.ru>
> ---
>  drivers/most/core.c     |  2 +-
>  drivers/most/most_usb.c | 11 ++++++-----
>  2 files changed, 7 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/most/core.c b/drivers/most/core.c
> index a635d5082ebb..10951171e72d 100644
> --- a/drivers/most/core.c
> +++ b/drivers/most/core.c
> @@ -1304,7 +1304,7 @@ int most_register_interface(struct most_interface *iface)
>  	iface->dev->bus = &mostbus;
>  	iface->dev->groups = interface_attr_groups;
>  	dev_set_drvdata(iface->dev, iface);
> -	if (device_register(iface->dev)) {
> +	if (device_add(iface->dev)) {
>  		dev_err(iface->dev, "Failed to register interface device\n");
>  		kfree(iface->p);
>  		put_device(iface->dev);
> diff --git a/drivers/most/most_usb.c b/drivers/most/most_usb.c
> index cf5be9c449a5..3ee7abd15a09 100644
> --- a/drivers/most/most_usb.c
> +++ b/drivers/most/most_usb.c
> @@ -973,8 +973,13 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
>  	mdev->usb_device = usb_dev;
>  	mdev->link_stat_timer.expires = jiffies + (2 * HZ);
>  
> +	device_initialize(&mdev->dev);
> +	mdev->dev.init_name = mdev->description;
> +	mdev->dev.parent = &interface->dev;
> +	mdev->dev.release = release_mdev;
> +
>  	mdev->iface.mod = hdm_usb_fops.owner;
> -	mdev->iface.dev = &mdev->dev;
> +	mdev->iface.dev = get_device(&mdev->dev);
>  	mdev->iface.driver_dev = &interface->dev;
>  	mdev->iface.interface = ITYPE_USB;
>  	mdev->iface.configure = hdm_configure_channel;
> @@ -993,9 +998,6 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
>  		 usb_dev->config->desc.bConfigurationValue,
>  		 usb_iface_desc->desc.bInterfaceNumber);
>  
> -	mdev->dev.init_name = mdev->description;
> -	mdev->dev.parent = &interface->dev;
> -	mdev->dev.release = release_mdev;
>  	mdev->conf = kcalloc(num_endpoints, sizeof(*mdev->conf), GFP_KERNEL);
>  	if (!mdev->conf)
>  		goto err_free_mdev;
> @@ -1126,7 +1128,6 @@ static void hdm_disconnect(struct usb_interface *interface)
>  	kfree(mdev->cap);
>  	kfree(mdev->conf);
>  	kfree(mdev->ep_address);
> -	put_device(&mdev->dci->dev);
>  	put_device(&mdev->dev);
>  }
>  
> -- 
> 2.49.0



More information about the lvc-project mailing list