Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Johan Hovold and committed by
Greg Kroah-Hartman
baadf2a5 96cf8500

+5 -9
+5 -9
drivers/most/most_usb.c
··· 1058 1058 1059 1059 ret = most_register_interface(&mdev->iface); 1060 1060 if (ret) 1061 - goto err_free_busy_urbs; 1061 + return ret; 1062 1062 1063 1063 mutex_lock(&mdev->io_mutex); 1064 1064 if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || ··· 1068 1068 if (!mdev->dci) { 1069 1069 mutex_unlock(&mdev->io_mutex); 1070 1070 most_deregister_interface(&mdev->iface); 1071 - ret = -ENOMEM; 1072 - goto err_free_busy_urbs; 1071 + return -ENOMEM; 1073 1072 } 1074 1073 1075 1074 mdev->dci->dev.init_name = "dci"; ··· 1077 1078 mdev->dci->dev.release = release_dci; 1078 1079 if (device_register(&mdev->dci->dev)) { 1079 1080 mutex_unlock(&mdev->io_mutex); 1081 + put_device(&mdev->dci->dev); 1080 1082 most_deregister_interface(&mdev->iface); 1081 - ret = -ENOMEM; 1082 - goto err_free_dci; 1083 + return -ENOMEM; 1083 1084 } 1084 1085 mdev->dci->usb_device = mdev->usb_device; 1085 1086 } 1086 1087 mutex_unlock(&mdev->io_mutex); 1087 1088 return 0; 1088 - err_free_dci: 1089 - put_device(&mdev->dci->dev); 1090 - err_free_busy_urbs: 1091 - kfree(mdev->busy_urbs); 1089 + 1092 1090 err_free_ep_address: 1093 1091 kfree(mdev->ep_address); 1094 1092 err_free_cap: