mirror of
https://github.com/torvalds/linux.git
synced 2025-11-30 23:16:01 +07:00
most: usb: fix double free on late probe failure
The MOST subsystem has a non-standard registration function which frees the interface on registration failures and on deregistration. This unsurprisingly leads to bugs in the MOST drivers, and a couple of recent changes turned a reference underflow and use-after-free in the USB driver into several double free and a use-after-free on late probe failures. Fixes:723de0f917("staging: most: remove device from interface structure") Fixes:4b12709026("most: usb: Fix use-after-free in hdm_disconnect") Fixes:a8cc9e5fcb("most: usb: hdm_probe: Fix calling put_device() before device initialization") Cc: stable@vger.kernel.org Cc: Christian Gromm <christian.gromm@microchip.com> Cc: Victoria Votokina <Victoria.Votokina@kaspersky.com> Signed-off-by: Johan Hovold <johan@kernel.org> Link: https://patch.msgid.link/20251029093029.28922-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
96cf850093
commit
baadf2a5c2
@@ -1058,7 +1058,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
|
||||
ret = most_register_interface(&mdev->iface);
|
||||
if (ret)
|
||||
goto err_free_busy_urbs;
|
||||
return ret;
|
||||
|
||||
mutex_lock(&mdev->io_mutex);
|
||||
if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 ||
|
||||
@@ -1068,8 +1068,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
if (!mdev->dci) {
|
||||
mutex_unlock(&mdev->io_mutex);
|
||||
most_deregister_interface(&mdev->iface);
|
||||
ret = -ENOMEM;
|
||||
goto err_free_busy_urbs;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mdev->dci->dev.init_name = "dci";
|
||||
@@ -1078,18 +1077,15 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
|
||||
mdev->dci->dev.release = release_dci;
|
||||
if (device_register(&mdev->dci->dev)) {
|
||||
mutex_unlock(&mdev->io_mutex);
|
||||
put_device(&mdev->dci->dev);
|
||||
most_deregister_interface(&mdev->iface);
|
||||
ret = -ENOMEM;
|
||||
goto err_free_dci;
|
||||
return -ENOMEM;
|
||||
}
|
||||
mdev->dci->usb_device = mdev->usb_device;
|
||||
}
|
||||
mutex_unlock(&mdev->io_mutex);
|
||||
return 0;
|
||||
err_free_dci:
|
||||
put_device(&mdev->dci->dev);
|
||||
err_free_busy_urbs:
|
||||
kfree(mdev->busy_urbs);
|
||||
|
||||
err_free_ep_address:
|
||||
kfree(mdev->ep_address);
|
||||
err_free_cap:
|
||||
|
||||
Reference in New Issue
Block a user