mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-01-11 17:10:13 +00: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: 723de0f9171e ("staging: most: remove device from interface structure")
Fixes: 4b1270902609 ("most: usb: Fix use-after-free in hdm_disconnect")
Fixes: a8cc9e5fcb0e ("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:
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:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user