* [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT
@ 2026-03-29 12:53 Sebastian Josue Alba Vives
2026-03-29 12:53 ` [PATCH] usbip: vhci: validate number_of_packets in RET_SUBMIT response Sebastian Josue Alba Vives
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: Sebastian Josue Alba Vives @ 2026-03-29 12:53 UTC (permalink / raw)
To: security; +Cc: gregkh, shuah, stable, Sebastián Alba Vives
A malicious USB/IP server can send a RET_SUBMIT response with
number_of_packets larger than the original URB allocation, causing
usbip_recv_iso() and usbip_pad_iso() to write beyond
urb->iso_frame_desc[], overflowing the kernel heap.
Attack chain:
1. Client sends isochronous URB with number_of_packets = N
2. usbip_pack_pdu() overwrites urb->number_of_packets with N'
3. usbip_recv_iso() loops N' times over iso_frame_desc[N] -> OOB
4. usbip_pad_iso() also loops with N' -> second OOB
CVE-2016-3955 fixed the same pattern in usbip_recv_xbuff() for
actual_length but missed number_of_packets in usbip_recv_iso().
stub_rx.c validates for CMD_SUBMIT but vhci_rx.c has no validation
for RET_SUBMIT.
Impact: Remote heap buffer overflow WRITE, no auth, attacker
controlled data, potential kernel code execution. Affects all
kernels with CONFIG_USBIP_VHCI_HCD since USB/IP integration.
Found through manual source code auditing.
Reported-by: Sebastián Alba Vives <sebasjosue84@gmail.com>
^ permalink raw reply [flat|nested] 9+ messages in thread* [PATCH] usbip: vhci: validate number_of_packets in RET_SUBMIT response 2026-03-29 12:53 [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Sebastian Josue Alba Vives @ 2026-03-29 12:53 ` Sebastian Josue Alba Vives 2026-03-29 13:25 ` Greg KH 2026-03-29 13:17 ` [SECURITY] usbip: iso_frame_desc OOB memmove via crafted offset/length Sebastian Josue Alba Vives 2026-03-29 13:24 ` [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Greg KH 2 siblings, 1 reply; 9+ messages in thread From: Sebastian Josue Alba Vives @ 2026-03-29 12:53 UTC (permalink / raw) To: security; +Cc: gregkh, shuah, stable, Sebastián Alba Vives From: Sebastián Alba Vives <sebasjosue84@gmail.com> vhci_recv_ret_submit() calls usbip_pack_pdu() which overwrites urb->number_of_packets with the value from the network PDU reply without any validation. A malicious USB/IP server can set number_of_packets to a value larger than the original URB allocation, causing usbip_recv_iso() and usbip_pad_iso() to access urb->iso_frame_desc[] entries beyond the allocated array. This leads to a heap buffer overflow in kernel memory, reachable over the network without authentication. The attack chain is: 1. Client sends isochronous URB with number_of_packets = N 2. Server replies with number_of_packets = N' >> N 3. usbip_pack_pdu() blindly copies N' into urb->number_of_packets 4. usbip_recv_iso() loops N' times over iso_frame_desc[N] → OOB 5. usbip_pad_iso() also loops N' times → second OOB Save the original number_of_packets before usbip_pack_pdu() and validate the returned value does not exceed it. Also add a defensive bounds check in usbip_recv_iso() against USBIP_MAX_ISO_PACKETS and use array_size() to prevent integer overflow in the allocation. Note that stub_rx.c already validates number_of_packets against USBIP_MAX_ISO_PACKETS for CMD_SUBMIT on the server side, but no equivalent validation existed on the client side for RET_SUBMIT. Cc: stable@vger.kernel.org Signed-off-by: Sebastián Alba Vives <sebasjosue84@gmail.com> --- drivers/usb/usbip/usbip_common.c | 18 ++++++++++++++---- drivers/usb/usbip/vhci_rx.c | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index a2b2da125..f1eeab3a5 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -662,7 +662,6 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) void *buff; struct usbip_iso_packet_descriptor *iso; int np = urb->number_of_packets; - int size = np * sizeof(*iso); int i; int ret; int total_length = 0; @@ -674,12 +673,23 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) if (np == 0) return 0; - buff = kzalloc(size, GFP_KERNEL); + /* + * Sanity check to prevent heap overflow. USBIP_MAX_ISO_PACKETS + * is validated on the stub (server) side for CMD_SUBMIT, but the + * client must also validate in case of a malicious server reply. + * Also rejects negative values. + */ + if (np < 0 || np > USBIP_MAX_ISO_PACKETS) { + dev_err(&urb->dev->dev, "recv iso: invalid np %d\n", np); + return -EPROTO; + } + + buff = kzalloc(array_size(np, sizeof(*iso)), GFP_KERNEL); if (!buff) return -ENOMEM; - ret = usbip_recv(ud->tcp_socket, buff, size); - if (ret != size) { + ret = usbip_recv(ud->tcp_socket, buff, np * sizeof(*iso)); + if (ret != np * sizeof(*iso)) { dev_err(&urb->dev->dev, "recv iso_frame_descriptor, %d\n", ret); kfree(buff); diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c index a75f4a898..4ca7cda62 100644 --- a/drivers/usb/usbip/vhci_rx.c +++ b/drivers/usb/usbip/vhci_rx.c @@ -60,6 +60,7 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, struct usbip_device *ud = &vdev->ud; struct urb *urb; unsigned long flags; + int orig_number_of_packets; spin_lock_irqsave(&vdev->priv_lock, flags); urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum); @@ -73,9 +74,35 @@ static void vhci_recv_ret_submit(struct vhci_device *vdev, return; } + /* + * Save the original number_of_packets before usbip_pack_pdu() + * overwrites it with the value from the network PDU. The + * iso_frame_desc array was allocated based on this original value, + * so the reply must not claim more packets than were originally + * submitted. + */ + orig_number_of_packets = urb->number_of_packets; + /* unpack the pdu to a urb */ usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0); + /* + * Validate that the server did not return more isochronous packets + * than were originally submitted. A malicious server could set + * number_of_packets to a value larger than the original, causing + * usbip_recv_iso() and usbip_pad_iso() to access iso_frame_desc + * entries beyond the allocated array, resulting in heap buffer + * overflow. + */ + if (urb->number_of_packets < 0 || + urb->number_of_packets > orig_number_of_packets) { + dev_err(&urb->dev->dev, + "pdu number_of_packets %d > original %d\n", + urb->number_of_packets, orig_number_of_packets); + urb->status = -EPROTO; + goto error; + } + /* recv transfer buffer */ if (usbip_recv_xbuff(ud, urb) < 0) { urb->status = -EPROTO; -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] usbip: vhci: validate number_of_packets in RET_SUBMIT response 2026-03-29 12:53 ` [PATCH] usbip: vhci: validate number_of_packets in RET_SUBMIT response Sebastian Josue Alba Vives @ 2026-03-29 13:25 ` Greg KH 0 siblings, 0 replies; 9+ messages in thread From: Greg KH @ 2026-03-29 13:25 UTC (permalink / raw) To: Sebastian Josue Alba Vives; +Cc: security, shuah, stable On Sun, Mar 29, 2026 at 06:53:33AM -0600, Sebastian Josue Alba Vives wrote: > From: Sebastián Alba Vives <sebasjosue84@gmail.com> > > vhci_recv_ret_submit() calls usbip_pack_pdu() which overwrites > urb->number_of_packets with the value from the network PDU reply > without any validation. A malicious USB/IP server can set > number_of_packets to a value larger than the original URB allocation, > causing usbip_recv_iso() and usbip_pad_iso() to access > urb->iso_frame_desc[] entries beyond the allocated array. > > This leads to a heap buffer overflow in kernel memory, reachable over > the network without authentication. > > The attack chain is: > 1. Client sends isochronous URB with number_of_packets = N > 2. Server replies with number_of_packets = N' >> N > 3. usbip_pack_pdu() blindly copies N' into urb->number_of_packets > 4. usbip_recv_iso() loops N' times over iso_frame_desc[N] → OOB > 5. usbip_pad_iso() also loops N' times → second OOB > > Save the original number_of_packets before usbip_pack_pdu() and > validate the returned value does not exceed it. Also add a defensive > bounds check in usbip_recv_iso() against USBIP_MAX_ISO_PACKETS and > use array_size() to prevent integer overflow in the allocation. > > Note that stub_rx.c already validates number_of_packets against > USBIP_MAX_ISO_PACKETS for CMD_SUBMIT on the server side, but no > equivalent validation existed on the client side for RET_SUBMIT. > > Cc: stable@vger.kernel.org > Signed-off-by: Sebastián Alba Vives <sebasjosue84@gmail.com> > --- > drivers/usb/usbip/usbip_common.c | 18 ++++++++++++++---- > drivers/usb/usbip/vhci_rx.c | 27 +++++++++++++++++++++++++++ > 2 files changed, 41 insertions(+), 4 deletions(-) Please see this series: https://lore.kernel.org/r/20260325104841.8282-1-addcontent08@gmail.com and this follow-on: https://lore.kernel.org/r/20260327064449.735-1-nathan.c.rebello@gmail.com and if both of your patches are still relevant after applying them, great, send them on as a follow-on patch please. thanks, greg k-h ^ permalink raw reply [flat|nested] 9+ messages in thread
* [SECURITY] usbip: iso_frame_desc OOB memmove via crafted offset/length 2026-03-29 12:53 [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Sebastian Josue Alba Vives 2026-03-29 12:53 ` [PATCH] usbip: vhci: validate number_of_packets in RET_SUBMIT response Sebastian Josue Alba Vives @ 2026-03-29 13:17 ` Sebastian Josue Alba Vives 2026-03-29 13:17 ` [PATCH] usbip: validate iso_frame_desc offset and length in usbip_recv_iso() Sebastian Josue Alba Vives 2026-03-29 13:24 ` [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Greg KH 2 siblings, 1 reply; 9+ messages in thread From: Sebastian Josue Alba Vives @ 2026-03-29 13:17 UTC (permalink / raw) To: security; +Cc: gregkh, shuah, stable, Sebastián Alba Vives This is a second vulnerability in the USB/IP iso receive path, independent from the number_of_packets issue in my previous patch. After usbip_recv_iso() unpacks iso_frame_desc entries from the network, the offset and actual_length fields are used by usbip_pad_iso() in memmove without validating against transfer_buffer_length. A malicious server can send valid number_of_packets but with crafted offset values exceeding the buffer, causing OOB memmove that corrupts kernel heap memory. No authentication required. The patch adds per-entry validation that offset + actual_length falls within transfer_buffer_length. Found through manual source code auditing. Reported-by: Sebastián Alba Vives <sebasjosue84@gmail.com> ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH] usbip: validate iso_frame_desc offset and length in usbip_recv_iso() 2026-03-29 13:17 ` [SECURITY] usbip: iso_frame_desc OOB memmove via crafted offset/length Sebastian Josue Alba Vives @ 2026-03-29 13:17 ` Sebastian Josue Alba Vives 0 siblings, 0 replies; 9+ messages in thread From: Sebastian Josue Alba Vives @ 2026-03-29 13:17 UTC (permalink / raw) To: security; +Cc: gregkh, shuah, stable, Sebastián Alba Vives From: Sebastián Alba Vives <sebasjosue84@gmail.com> usbip_recv_iso() receives isochronous packet descriptors from the network and unpacks them into urb->iso_frame_desc[] via usbip_pack_iso(). The offset and actual_length fields in each descriptor come directly from the remote peer without validation. These fields are subsequently used by usbip_pad_iso() in memmove operations: memmove(urb->transfer_buffer + iso_frame_desc[i].offset, urb->transfer_buffer + actualoffset, iso_frame_desc[i].actual_length); A malicious USB/IP server can craft iso frame descriptors with offset and/or actual_length values exceeding the transfer buffer bounds, causing an out-of-bounds memmove that corrupts kernel heap memory. This is exploitable over the network without authentication. This is a separate vulnerability from the number_of_packets validation issue. Even with a valid number_of_packets, the individual descriptor fields can still cause OOB access. Add validation that each iso_frame_desc entry's offset + actual_length falls within the transfer buffer bounds. Return -EPROTO and trigger a connection reset if any entry is invalid. Cc: stable@vger.kernel.org Signed-off-by: Sebastián Alba Vives <sebasjosue84@gmail.com> --- drivers/usb/usbip/usbip_common.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index f1eeab3a5..8b6ca8f83 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -711,6 +711,34 @@ int usbip_recv_iso(struct usbip_device *ud, struct urb *urb) kfree(buff); + /* + * Validate each iso_frame_desc entry. The offset and actual_length + * come from the network and must not exceed the transfer buffer. + * Without this check, a malicious server could craft iso descriptors + * with out-of-bounds offset/length values, causing usbip_pad_iso() + * to perform memmove operations beyond the transfer buffer, leading + * to heap buffer overflow. + */ + for (i = 0; i < np; i++) { + unsigned int offset = urb->iso_frame_desc[i].offset; + unsigned int length = urb->iso_frame_desc[i].actual_length; + + if (offset > urb->transfer_buffer_length || + length > urb->transfer_buffer_length - offset) { + dev_err(&urb->dev->dev, + "iso frame %d: offset %u + length %u > buffer %u\n", + i, offset, length, + urb->transfer_buffer_length); + + if (ud->side == USBIP_STUB || ud->side == USBIP_VUDC) + usbip_event_add(ud, SDEV_EVENT_ERROR_TCP); + else + usbip_event_add(ud, VDEV_EVENT_ERROR_TCP); + + return -EPROTO; + } + } + if (total_length != urb->actual_length) { dev_err(&urb->dev->dev, "total length of iso packets %d not equal to actual length of buffer %d\n", -- 2.43.0 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT 2026-03-29 12:53 [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Sebastian Josue Alba Vives 2026-03-29 12:53 ` [PATCH] usbip: vhci: validate number_of_packets in RET_SUBMIT response Sebastian Josue Alba Vives 2026-03-29 13:17 ` [SECURITY] usbip: iso_frame_desc OOB memmove via crafted offset/length Sebastian Josue Alba Vives @ 2026-03-29 13:24 ` Greg KH 2026-03-29 13:34 ` Sebastián Alba 2 siblings, 1 reply; 9+ messages in thread From: Greg KH @ 2026-03-29 13:24 UTC (permalink / raw) To: Sebastian Josue Alba Vives; +Cc: security, shuah, stable On Sun, Mar 29, 2026 at 06:53:32AM -0600, Sebastian Josue Alba Vives wrote: > A malicious USB/IP server can send a RET_SUBMIT response with > number_of_packets larger than the original URB allocation, causing > usbip_recv_iso() and usbip_pad_iso() to write beyond > urb->iso_frame_desc[], overflowing the kernel heap. Ok, this is just getting funny now... What is the AI prompt that you all are using to "find" these usbip "security bugs"? This is like the 3rd or 4th "report" of this in the past week or so. Anyway, as always, the usbip connection is considered "trusted", never connect to a usbip device you do not trust (on either side), and patches for this where invalid packets are sent are always appreciated. Note, patches for this have been sent on the linux-usb mailing list in the past few days, so you might want to have checked there first to be sure you didn't create the same thing that others have already submitted. thanks, greg k-h ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT 2026-03-29 13:24 ` [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Greg KH @ 2026-03-29 13:34 ` Sebastián Alba 2026-03-29 13:50 ` Greg KH 0 siblings, 1 reply; 9+ messages in thread From: Sebastián Alba @ 2026-03-29 13:34 UTC (permalink / raw) To: Greg KH; +Cc: security, shuah, stable Hi Greg, You're right...I see the patches from Kelvin and Nathan on linux-usb now. I should have checked lore before sending. No AI prompt, just manual auditing starting from CVE-2016-3955, but clearly others had the same idea this week. Sorry for the noise, and thanks for pointing me in the right direction. I'll check linux-usb first next time. El dom, 29 mar 2026 a las 7:25, Greg KH (<gregkh@linuxfoundation.org>) escribió: > > On Sun, Mar 29, 2026 at 06:53:32AM -0600, Sebastian Josue Alba Vives wrote: > > A malicious USB/IP server can send a RET_SUBMIT response with > > number_of_packets larger than the original URB allocation, causing > > usbip_recv_iso() and usbip_pad_iso() to write beyond > > urb->iso_frame_desc[], overflowing the kernel heap. > > Ok, this is just getting funny now... > > What is the AI prompt that you all are using to "find" these usbip > "security bugs"? This is like the 3rd or 4th "report" of this in the > past week or so. > > Anyway, as always, the usbip connection is considered "trusted", never > connect to a usbip device you do not trust (on either side), and patches > for this where invalid packets are sent are always appreciated. > > Note, patches for this have been sent on the linux-usb mailing list in > the past few days, so you might want to have checked there first to be > sure you didn't create the same thing that others have already > submitted. > > thanks, > > greg k-h -- Sebastián Alba ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT 2026-03-29 13:34 ` Sebastián Alba @ 2026-03-29 13:50 ` Greg KH 2026-03-29 13:53 ` Sebastián Alba 0 siblings, 1 reply; 9+ messages in thread From: Greg KH @ 2026-03-29 13:50 UTC (permalink / raw) To: Sebastián Alba; +Cc: security, shuah, stable On Sun, Mar 29, 2026 at 07:34:22AM -0600, Sebastián Alba wrote: > Hi Greg, You're right...I see the patches from Kelvin and Nathan on > linux-usb now. I should have checked lore before sending. No AI > prompt, just manual auditing starting from CVE-2016-3955, but clearly > others had the same idea this week. Sorry for the noise, and thanks > for pointing me in the right direction. I'll check linux-usb first > next time. Curious as to _why_ 3 different people all independantly decided to look at CVE-2016-3955, a 10 year old CVE entry, and decide this week to poke at this on their own and come up with almost the same exact issues. What made that specific CVE stand out in the see of tens of thousands of other kernel CVEs out there? thanks, greg k-h ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT 2026-03-29 13:50 ` Greg KH @ 2026-03-29 13:53 ` Sebastián Alba 0 siblings, 0 replies; 9+ messages in thread From: Sebastián Alba @ 2026-03-29 13:53 UTC (permalink / raw) To: Greg KH; +Cc: security, shuah, stable It was presented at Black Hat Asia 2017 by Ignat Korchagin with a full writeup explaining the pattern. When you audit USB/IP for similar issues, CVE-2016-3955 is the obvious starting point because the writeup literally walks through vhci_recv_ret_submit and usbip_recv_xbuff step by step. From there, checking if the same pattern exists in usbip_recv_iso and usbip_pad_iso is the natural next step. I imagine the others followed the same trail... El dom, 29 mar 2026 a las 7:51, Greg KH (<gregkh@linuxfoundation.org>) escribió: > > On Sun, Mar 29, 2026 at 07:34:22AM -0600, Sebastián Alba wrote: > > Hi Greg, You're right...I see the patches from Kelvin and Nathan on > > linux-usb now. I should have checked lore before sending. No AI > > prompt, just manual auditing starting from CVE-2016-3955, but clearly > > others had the same idea this week. Sorry for the noise, and thanks > > for pointing me in the right direction. I'll check linux-usb first > > next time. > > Curious as to _why_ 3 different people all independantly decided to look > at CVE-2016-3955, a 10 year old CVE entry, and decide this week to poke > at this on their own and come up with almost the same exact issues. > > What made that specific CVE stand out in the see of tens of thousands of > other kernel CVEs out there? > > thanks, > > greg k-h -- Sebastián Alba ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-03-29 13:53 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-03-29 12:53 [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Sebastian Josue Alba Vives 2026-03-29 12:53 ` [PATCH] usbip: vhci: validate number_of_packets in RET_SUBMIT response Sebastian Josue Alba Vives 2026-03-29 13:25 ` Greg KH 2026-03-29 13:17 ` [SECURITY] usbip: iso_frame_desc OOB memmove via crafted offset/length Sebastian Josue Alba Vives 2026-03-29 13:17 ` [PATCH] usbip: validate iso_frame_desc offset and length in usbip_recv_iso() Sebastian Josue Alba Vives 2026-03-29 13:24 ` [SECURITY] usbip: vhci: heap buffer overflow via crafted number_of_packets in RET_SUBMIT Greg KH 2026-03-29 13:34 ` Sebastián Alba 2026-03-29 13:50 ` Greg KH 2026-03-29 13:53 ` Sebastián Alba
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox