public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] usb: xhci: fix potential divide-by-zero in xhci_urb_enqueue()
@ 2026-01-10 18:34 pip-izony
  2026-01-10 20:02 ` Greg Kroah-Hartman
  2026-01-10 22:08 ` Alan Stern
  0 siblings, 2 replies; 4+ messages in thread
From: pip-izony @ 2026-01-10 18:34 UTC (permalink / raw)
  To: Mathias Nyman, Greg Kroah-Hartman
  Cc: Seungjin Bae, Kyungtae Kim, Reyad Attiyat, linux-usb,
	linux-kernel

From: Seungjin Bae <eeodqql09@gmail.com>

The `xhci_urb_enqueue()` validates Bulk OUT transfers by checking if the
buffer length is a multiple of the packet size. However, it doesn't check
whether the endpoint's `wMaxPacketSize` is zero before using it as a
divisor in a modulo operation.

If a malicious USB device sends a descriptor with `wMaxPacketSize` set to
0, it triggers a divide-by-zero exception (kernel panic). This allows an
attacker with physical access to crash the system, leading to a Denial of
Service.

Fix this by adding a check to ensure `wMaxPacketSize` is greater than 0
before performing the modulo operation.

Fixes: 4758dcd19a7d ("usb: xhci: Add support for URB_ZERO_PACKET to bulk/sg transfers")
Signed-off-by: Seungjin Bae <eeodqql09@gmail.com>
---
 drivers/usb/host/xhci.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 0cb45b95e4f5..f22ee6cc3083 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1621,15 +1621,18 @@ static int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flag
 	unsigned int *ep_state;
 	struct urb_priv	*urb_priv;
 	int num_tds;
+	int maxp;
 
 	ep_index = xhci_get_endpoint_index(&urb->ep->desc);
+	maxp = usb_endpoint_maxp(&urb->ep->desc);
 
 	if (usb_endpoint_xfer_isoc(&urb->ep->desc))
 		num_tds = urb->number_of_packets;
 	else if (usb_endpoint_is_bulk_out(&urb->ep->desc) &&
 	    urb->transfer_buffer_length > 0 &&
 	    urb->transfer_flags & URB_ZERO_PACKET &&
-	    !(urb->transfer_buffer_length % usb_endpoint_maxp(&urb->ep->desc)))
+		maxp > 0 &&
+	    !(urb->transfer_buffer_length % maxp))
 		num_tds = 2;
 	else
 		num_tds = 1;
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] usb: xhci: fix potential divide-by-zero in xhci_urb_enqueue()
  2026-01-10 18:34 [PATCH] usb: xhci: fix potential divide-by-zero in xhci_urb_enqueue() pip-izony
@ 2026-01-10 20:02 ` Greg Kroah-Hartman
  2026-01-10 22:08 ` Alan Stern
  1 sibling, 0 replies; 4+ messages in thread
From: Greg Kroah-Hartman @ 2026-01-10 20:02 UTC (permalink / raw)
  To: pip-izony
  Cc: Mathias Nyman, Kyungtae Kim, Reyad Attiyat, linux-usb,
	linux-kernel

On Sat, Jan 10, 2026 at 01:34:21PM -0500, pip-izony wrote:
> From: Seungjin Bae <eeodqql09@gmail.com>
> 
> The `xhci_urb_enqueue()` validates Bulk OUT transfers by checking if the
> buffer length is a multiple of the packet size. However, it doesn't check
> whether the endpoint's `wMaxPacketSize` is zero before using it as a
> divisor in a modulo operation.
> 
> If a malicious USB device sends a descriptor with `wMaxPacketSize` set to
> 0, it triggers a divide-by-zero exception (kernel panic). This allows an
> attacker with physical access to crash the system, leading to a Denial of
> Service.

Shouldn't such a device have been rejected before it got here?  When can
this happen, after a driver is bound to a device or before it?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] usb: xhci: fix potential divide-by-zero in xhci_urb_enqueue()
  2026-01-10 18:34 [PATCH] usb: xhci: fix potential divide-by-zero in xhci_urb_enqueue() pip-izony
  2026-01-10 20:02 ` Greg Kroah-Hartman
@ 2026-01-10 22:08 ` Alan Stern
  2026-01-12  9:30   ` Mathias Nyman
  1 sibling, 1 reply; 4+ messages in thread
From: Alan Stern @ 2026-01-10 22:08 UTC (permalink / raw)
  To: pip-izony
  Cc: Mathias Nyman, Greg Kroah-Hartman, Kyungtae Kim, Reyad Attiyat,
	linux-usb, linux-kernel

On Sat, Jan 10, 2026 at 01:34:21PM -0500, pip-izony wrote:
> From: Seungjin Bae <eeodqql09@gmail.com>
> 
> The `xhci_urb_enqueue()` validates Bulk OUT transfers by checking if the
> buffer length is a multiple of the packet size. However, it doesn't check
> whether the endpoint's `wMaxPacketSize` is zero before using it as a
> divisor in a modulo operation.
> 
> If a malicious USB device sends a descriptor with `wMaxPacketSize` set to
> 0, it triggers a divide-by-zero exception (kernel panic). This allows an
> attacker with physical access to crash the system, leading to a Denial of
> Service.

How did you become aware of this problem?

> Fix this by adding a check to ensure `wMaxPacketSize` is greater than 0
> before performing the modulo operation.

Not necessary.  This can never happen, because transfers to or from 
endpoints with wMaxPacketSize set to 0 are rejected in usb_submit_urb() 
with error code -EMSGSIZE.

Alan Stern

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] usb: xhci: fix potential divide-by-zero in xhci_urb_enqueue()
  2026-01-10 22:08 ` Alan Stern
@ 2026-01-12  9:30   ` Mathias Nyman
  0 siblings, 0 replies; 4+ messages in thread
From: Mathias Nyman @ 2026-01-12  9:30 UTC (permalink / raw)
  To: Alan Stern, pip-izony
  Cc: Mathias Nyman, Greg Kroah-Hartman, Kyungtae Kim, Reyad Attiyat,
	linux-usb, linux-kernel

On 1/11/26 00:08, Alan Stern wrote:
> On Sat, Jan 10, 2026 at 01:34:21PM -0500, pip-izony wrote:
>> From: Seungjin Bae <eeodqql09@gmail.com>
>>
>> The `xhci_urb_enqueue()` validates Bulk OUT transfers by checking if the
>> buffer length is a multiple of the packet size. However, it doesn't check
>> whether the endpoint's `wMaxPacketSize` is zero before using it as a
>> divisor in a modulo operation.
>>
>> If a malicious USB device sends a descriptor with `wMaxPacketSize` set to
>> 0, it triggers a divide-by-zero exception (kernel panic). This allows an
>> attacker with physical access to crash the system, leading to a Denial of
>> Service.
> 
> How did you become aware of this problem?
> 
>> Fix this by adding a check to ensure `wMaxPacketSize` is greater than 0
>> before performing the modulo operation.
> 
> Not necessary.  This can never happen, because transfers to or from
> endpoints with wMaxPacketSize set to 0 are rejected in usb_submit_urb()
> with error code -EMSGSIZE.
> 

Only special embedded high-speed eUSB double isoch bandwidth devices can have
isoch endpoints with wMaxPacketSize set to zero.

This divide by zero case is only an issue for Bulk OUT endpoints, which as Alan
said, will be rejected by usb_submit_urb()

Thanks
Mathias

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-01-12  9:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-10 18:34 [PATCH] usb: xhci: fix potential divide-by-zero in xhci_urb_enqueue() pip-izony
2026-01-10 20:02 ` Greg Kroah-Hartman
2026-01-10 22:08 ` Alan Stern
2026-01-12  9:30   ` Mathias Nyman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox