Thread (4 messages) 4 messages, 2 authors, 2026-09-09

[PATCH v2] usbip: fix number_of_packets for non-iso transfers

flat view
DORMANTno replies

From: Markus Mikonsaari <hidden>
Date: 2026-09-09 12:06:28
Subsystem: the rest, usb over ip driver, usb subsystem · Maintainers: Linus Torvalds, Valentina Manea, Shuah Khan, Shuah Khan, Greg Kroah-Hartman

In the USB/IP protocol, number_of_packets is set to 0xffffffff (-1)
by sender when the transfer is not isochronous.
usbip_pack_pdu() copies this value into urb->number_of_packets.

A host controller driver may compute the iso_frame_desc size directly
from number_of_packets without independently validating it against 
the pipe type which produces an undersized allocation.
For example on a Raspberry Pi, the dwc_otg driver panics with a 
slab-out-of-bounds write in dwc_otg_hcd_urb_alloc() during a 
USB/IP attach involving a non-isochronous transfer.

Correct the number_of_packets to the value the urb was actually
allocated for immediately after usbip_pack_pdu() overwrites it.

Assisted-by: LLM
Signed-off-by: Markus Mikonsaari <redacted>
---
v2: 
  - Moved fix and comment into a static helper
  - Shortened summary
  - Added Assisted-by tag

 drivers/usb/usbip/stub_rx.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
diff --git a/drivers/usb/usbip/stub_rx.c b/drivers/usb/usbip/stub_rx.c
index 1e9ae578810d..d592fd8edd87 100644
--- a/drivers/usb/usbip/stub_rx.c
+++ b/drivers/usb/usbip/stub_rx.c
@@ -461,6 +461,20 @@ static int stub_recv_xbuff(struct usbip_device *ud, struct stub_priv *priv)
 	return ret;
 }
 
+/*
+ * number_of_packets is set to -1 by the USB/IP sender when the transfer
+ * is not isochronous.
+ * usbip_pack_pdu() copies this value into urb->number_of_packets.
+ * Leaving the number_of_packets at -1 can lead to
+ * downstream consumers of this urb (e.g. host-controller drivers)
+ * to allocate negative iso_frame_desc storage.
+ * Set it to what the urb was actually allocated for.
+ */
+static inline void stub_fixup_urb_number_of_packets(struct urb *urb, int np)
+{
+	urb->number_of_packets = np;
+}
+
 static void stub_recv_cmd_submit(struct stub_device *sdev,
 				 struct usbip_header *pdu)
 {
@@ -567,6 +581,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
 		}
 
 		usbip_pack_pdu(pdu, priv->urbs[0], USBIP_CMD_SUBMIT, 0);
+		stub_fixup_urb_number_of_packets(priv->urbs[0], np);
 	} else {
 		for_each_sg(sgl, sg, nents, i) {
 			priv->urbs[i] = usb_alloc_urb(0, GFP_KERNEL);
@@ -579,6 +594,7 @@ static void stub_recv_cmd_submit(struct stub_device *sdev,
 			usbip_pack_pdu(pdu, priv->urbs[i], USBIP_CMD_SUBMIT, 0);
 			priv->urbs[i]->transfer_buffer = sg_virt(sg);
 			priv->urbs[i]->transfer_buffer_length = sg->length;
+			stub_fixup_urb_number_of_packets(priv->urbs[i], 0);
 		}
 		priv->sgl = sgl;
 	}
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help