[RFC 14/15] 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 8e5f0c3..6bcfc13 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1774,6 +1774,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...
@@ -1794,6 +1808,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) {
@@ -1812,6 +1828,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