Skip to content

Commit 2274767

Browse files
jhovoldgregkh
authored andcommitted
most: usb: fix double free on late probe failure
commit baadf2a upstream. 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: 723de0f ("staging: most: remove device from interface structure") Fixes: 4b12709 ("most: usb: Fix use-after-free in hdm_disconnect") Fixes: a8cc9e5 ("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>
1 parent 8fef76f commit 2274767

File tree

1 file changed

+5
-9
lines changed

1 file changed

+5
-9
lines changed

drivers/most/most_usb.c

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
10581058

10591059
ret = most_register_interface(&mdev->iface);
10601060
if (ret)
1061-
goto err_free_busy_urbs;
1061+
return ret;
10621062

10631063
mutex_lock(&mdev->io_mutex);
10641064
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)
10681068
if (!mdev->dci) {
10691069
mutex_unlock(&mdev->io_mutex);
10701070
most_deregister_interface(&mdev->iface);
1071-
ret = -ENOMEM;
1072-
goto err_free_busy_urbs;
1071+
return -ENOMEM;
10731072
}
10741073

10751074
mdev->dci->dev.init_name = "dci";
@@ -1078,18 +1077,15 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id)
10781077
mdev->dci->dev.release = release_dci;
10791078
if (device_register(&mdev->dci->dev)) {
10801079
mutex_unlock(&mdev->io_mutex);
1080+
put_device(&mdev->dci->dev);
10811081
most_deregister_interface(&mdev->iface);
1082-
ret = -ENOMEM;
1083-
goto err_free_dci;
1082+
return -ENOMEM;
10841083
}
10851084
mdev->dci->usb_device = mdev->usb_device;
10861085
}
10871086
mutex_unlock(&mdev->io_mutex);
10881087
return 0;
1089-
err_free_dci:
1090-
put_device(&mdev->dci->dev);
1091-
err_free_busy_urbs:
1092-
kfree(mdev->busy_urbs);
1088+
10931089
err_free_ep_address:
10941090
kfree(mdev->ep_address);
10951091
err_free_cap:

0 commit comments

Comments
 (0)