Commit 9c6a9d7c8be40f58cf3faf0a4b8d9d33a21ca4f5

Authored by Kuo-Jung Su
Committed by Marek Vasut
1 parent f6664ba4bc

usb: ehci: prevent bad PORTSC register access

1. The 'index' of ehci_submit_root() is not always > 0.

   e.g.
   While it gets invoked from usb_get_descriptor(),
   the 'index' is always a '0'. (See ch.9 of USB2.0)

2. The PORTSC register is not always required, and thus it
   should only report a port error when necessary.
   It would cause a port scan failure if the ehci_submit_root()
   always gets terminated by a port error.

Signed-off-by: Kuo-Jung Su <dantesu@faraday-tech.com>
CC: Marek Vasut <marex@denx.de>

Showing 1 changed file with 15 additions and 5 deletions Side-by-side Diff

drivers/usb/host/ehci-hcd.c
... ... @@ -616,11 +616,6 @@
616 616 int port = le16_to_cpu(req->index) & 0xff;
617 617 struct ehci_ctrl *ctrl = dev->controller;
618 618  
619   - if (port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
620   - printf("The request port(%d) is not configured\n", port - 1);
621   - return -1;
622   - }
623   - status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
624 619 srclen = 0;
625 620  
626 621 debug("req=%u (%#x), type=%u (%#x), value=%u, index=%u\n",
... ... @@ -629,6 +624,21 @@
629 624 le16_to_cpu(req->value), le16_to_cpu(req->index));
630 625  
631 626 typeReq = req->request | req->requesttype << 8;
  627 +
  628 + switch (typeReq) {
  629 + case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
  630 + case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
  631 + case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
  632 + if (!port || port > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
  633 + printf("The request port(%d) is not configured\n", port - 1);
  634 + return -1;
  635 + }
  636 + status_reg = (uint32_t *)&ctrl->hcor->or_portsc[port - 1];
  637 + break;
  638 + default:
  639 + status_reg = NULL;
  640 + break;
  641 + }
632 642  
633 643 switch (typeReq) {
634 644 case DeviceRequest | USB_REQ_GET_DESCRIPTOR: