Re: [syzbot] KASAN: slab-use-after-free Read in vhci_send_cmd_submit

Edward Adam Davis <[email protected]>
Newsgroups org.kernel.vger.linux-kernel
Message-ID <[email protected]>
#syz test

diff --git a/drivers/usb/usbip/vhci_tx.c b/drivers/usb/usbip/vhci_tx.c
index 32e6fabccf72..c3aacbb6939f 100644
--- a/drivers/usb/usbip/vhci_tx.c
+++ b/drivers/usb/usbip/vhci_tx.c
@@ -13,7 +13,12 @@
 static void setup_cmd_submit_pdu(struct usbip_header *pdup,  struct urb *urb)
 {
 	struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
-	struct vhci_device *vdev = priv->vdev;
+	struct vhci_device *vdev;
+
+	if (!priv)
+		return;
+
+	vdev = priv->vdev;
 
 	usbip_dbg_vhci_tx("URB, local devnum %u, remote devid %u\n",
 			  usb_pipedevice(urb->pipe), vdev->devid);
@@ -68,7 +73,9 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 		int ret;
 		struct urb *urb = priv->urb;
 		struct usbip_header pdu_header;
+		unsigned long flags;
 
+		usb_get_urb(urb);
 		txsize = 0;
 		memset(&pdu_header, 0, sizeof(pdu_header));
 		memset(&msg, 0, sizeof(msg));
@@ -85,6 +92,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 		iov = kzalloc_objs(*iov, iovnum);
 		if (!iov) {
 			usbip_event_add(&vdev->ud, SDEV_EVENT_ERROR_MALLOC);
+			usb_put_urb(urb);
 			return -ENOMEM;
 		}
 
@@ -92,7 +100,14 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 			urb->transfer_flags |= URB_DMA_MAP_SG;
 
 		/* 1. setup usbip_header */
+		spin_lock_irqsave(&vdev->priv_lock, flags);
+		if (!urb->hcpriv) {
+			usb_put_urb(urb);
+			spin_unlock_irqrestore(&vdev->priv_lock, flags);
+			return -EIO;
+		}
 		setup_cmd_submit_pdu(&pdu_header, urb);
+		spin_unlock_irqrestore(&vdev->priv_lock, flags);
 		usbip_header_correct_endian(&pdu_header, 1);
 		iovnum = 0;
 
@@ -127,6 +142,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 			if (!iso_buffer) {
 				usbip_event_add(&vdev->ud,
 						SDEV_EVENT_ERROR_MALLOC);
+				usb_put_urb(urb);
 				goto err_iso_buffer;
 			}
 
@@ -143,6 +159,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 			       txsize);
 			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
 			err = -EPIPE;
+			usb_put_urb(urb);
 			goto err_tx;
 		}
 
@@ -154,6 +171,7 @@ static int vhci_send_cmd_submit(struct vhci_device *vdev)
 		usbip_dbg_vhci_tx("send txdata\n");
 
 		total_size += txsize;
+		usb_put_urb(urb);
 	}
 
 	return total_size;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.