Skip to content

Commit

Permalink
usb: vhci-hcd: Do not drop references before new references are gained
Browse files Browse the repository at this point in the history
commit afdcfd3 upstream.

At a few places the driver carries stale pointers
to references that can still be used. Make sure that does not happen.
This strictly speaking closes ZDI-CAN-22273, though there may be
similar races in the driver.

Signed-off-by: Oliver Neukum <[email protected]>
Cc: stable <[email protected]>
Acked-by: Shuah Khan <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
oneukum authored and gregkh committed Aug 14, 2024
1 parent 2262801 commit 128e82e
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions drivers/usb/usbip/vhci_hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,7 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
*
*/
if (usb_pipedevice(urb->pipe) == 0) {
struct usb_device *old;
__u8 type = usb_pipetype(urb->pipe);
struct usb_ctrlrequest *ctrlreq =
(struct usb_ctrlrequest *) urb->setup_packet;
Expand All @@ -755,14 +756,15 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
goto no_need_xmit;
}

old = vdev->udev;
switch (ctrlreq->bRequest) {
case USB_REQ_SET_ADDRESS:
/* set_address may come when a device is reset */
dev_info(dev, "SetAddress Request (%d) to port %d\n",
ctrlreq->wValue, vdev->rhport);

usb_put_dev(vdev->udev);
vdev->udev = usb_get_dev(urb->dev);
usb_put_dev(old);

spin_lock(&vdev->ud.lock);
vdev->ud.status = VDEV_ST_USED;
Expand All @@ -781,8 +783,8 @@ static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
usbip_dbg_vhci_hc(
"Not yet?:Get_Descriptor to device 0 (get max pipe size)\n");

usb_put_dev(vdev->udev);
vdev->udev = usb_get_dev(urb->dev);
usb_put_dev(old);
goto out;

default:
Expand Down Expand Up @@ -1067,15 +1069,16 @@ static void vhci_shutdown_connection(struct usbip_device *ud)
static void vhci_device_reset(struct usbip_device *ud)
{
struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
struct usb_device *old = vdev->udev;
unsigned long flags;

spin_lock_irqsave(&ud->lock, flags);

vdev->speed = 0;
vdev->devid = 0;

usb_put_dev(vdev->udev);
vdev->udev = NULL;
usb_put_dev(old);

if (ud->tcp_socket) {
sockfd_put(ud->tcp_socket);
Expand Down

0 comments on commit 128e82e

Please sign in to comment.