Commit fe8432ca authored by Oliver Neukum's avatar Oliver Neukum Committed by Zheng Yejian
Browse files

usb: vhci-hcd: Do not drop references before new references are gained

stable inclusion
from stable-v5.10.224
commit 4dacdb9720aaab10b6be121eae55820174d97174
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAM59O
CVE: CVE-2024-43883

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4dacdb9720aaab10b6be121eae55820174d97174



--------------------------------

commit afdcfd3d6fcdeca2735ca8d994c5f2d24a368f0a 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: default avatarOliver Neukum <oneukum@suse.com>
Cc: stable <stable@kernel.org>
Acked-by: default avatarShuah Khan <skhan@linuxfoundation.org>
Link: https://lore.kernel.org/r/20240709113851.14691-1-oneukum@suse.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarZheng Yejian <zhengyejian1@huawei.com>
parent b17777fc
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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:
@@ -1095,6 +1097,7 @@ 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);
@@ -1102,8 +1105,8 @@ static void vhci_device_reset(struct usbip_device *ud)
	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);