[RFC 17/22] xhci: Limit roothub ports to 15 USB3 & 31 USB2 ports.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The USB core allocates a USB 2.0 roothub descriptor that has room for 31
(USB_MAXCHILDREN) ports' worth of DeviceRemovable and PortPwrCtrlMask
fields.  Limit the number of USB 2.0 roothub ports accordingly.  I don't
expect to run into this limitation ever, but this prevents a buffer
overflow issue in the roothub descriptor filling code.

Similarly, a USB 3.0 hub can only have 15 downstream ports, so limit the
USB 3.0 roothub to 15 USB 3.0 ports.

Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
---
 drivers/usb/host/xhci-mem.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 76e4b95..6f30635 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1804,6 +1804,20 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
 	}
 	xhci_dbg(xhci, "Found %u USB 2.0 ports and %u USB 3.0 ports.\n",
 			xhci->num_usb2_ports, xhci->num_usb3_ports);
+
+	/* Place limits on the number of roothub ports so that the hub
+	 * descriptors aren't longer than the USB core will allocate.
+	 */
+	if (xhci->num_usb3_ports > 15) {
+		xhci_dbg(xhci, "Limiting USB 3.0 roothub ports to 15.\n");
+		xhci->num_usb3_ports = 15;
+	}
+	if (xhci->num_usb2_ports > USB_MAXCHILDREN) {
+		xhci_dbg(xhci, "Limiting USB 2.0 roothub ports to %u.\n",
+				USB_MAXCHILDREN);
+		xhci->num_usb2_ports = USB_MAXCHILDREN;
+	}
+
 	/*
 	 * Note we could have all USB 3.0 ports, or all USB 2.0 ports.
 	 * Not sure how the USB core will handle a hub with no ports...
@@ -1828,6 +1842,8 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
 					"addr = %p\n", i,
 					xhci->usb2_ports[port_index]);
 			port_index++;
+			if (port_index == xhci->num_usb2_ports)
+				break;
 		}
 	}
 	if (xhci->num_usb3_ports) {
@@ -1846,6 +1862,8 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
 						"addr = %p\n", i,
 						xhci->usb3_ports[port_index]);
 				port_index++;
+				if (port_index == xhci->num_usb3_ports)
+					break;
 			}
 	}
 	return 0;
-- 
1.6.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux