]> git.hungrycats.org Git - linux/commitdiff
dwc_otg: prevent BUG() in TT allocation if hub address is > 16
authorP33M <P33M@github.com>
Mon, 22 Jul 2013 13:08:26 +0000 (14:08 +0100)
committerP33M <P33M@github.com>
Mon, 22 Jul 2013 13:08:26 +0000 (14:08 +0100)
A fixed-size array is used to track TT allocation. This was
previously set to 16 which caused a crash because
dwc_otg_hcd_allocate_port would read past the end of the array.

This was hit if a hub was plugged in which enumerated as addr > 16,
due to previous device resets or unplugs.

Also add #ifdef FIQ_DEBUG around hcd->hub_port_alloc[], which grows
to a large size if 128 hub addresses are supported. This field is
for debug only for tracking which frame an allocate happened in.

drivers/usb/host/dwc_otg/dwc_otg_hcd.c
drivers/usb/host/dwc_otg/dwc_otg_hcd.h
drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c

index a1970dcd08e7280547bcb82accef6d5c8c299e1f..3c619b4f3a14738583ba42e431cc6484eb4be3a7 100644 (file)
@@ -983,7 +983,9 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if)
        hcd->periodic_qh_count = 0;
 
        DWC_MEMSET(hcd->hub_port, 0, sizeof(hcd->hub_port));
+#ifdef FIQ_DEBUG
        DWC_MEMSET(hcd->hub_port_alloc, -1, sizeof(hcd->hub_port_alloc));
+#endif
 
 out:
        return retval;
@@ -1317,7 +1319,9 @@ int dwc_otg_hcd_allocate_port(dwc_otg_hcd_t * hcd, dwc_otg_qh_t *qh)
                qh->skip_count = 0;
                hcd->hub_port[hub_addr] |= 1 << port_addr;
                fiq_print(FIQDBG_PORTHUB, "H%dP%d:A %d", hub_addr, port_addr, DWC_CIRCLEQ_FIRST(&qh->qtd_list)->urb->pipe_info.ep_num);
+#ifdef FIQ_DEBUG
                hcd->hub_port_alloc[hub_addr * 16 + port_addr] = dwc_otg_hcd_get_frame_number(hcd);
+#endif
                return 0;
        }
 }
@@ -1331,8 +1335,9 @@ void dwc_otg_hcd_release_port(dwc_otg_hcd_t * hcd, dwc_otg_qh_t *qh)
        hcd->fops->hub_info(hcd, DWC_CIRCLEQ_FIRST(&qh->qtd_list)->urb->priv, &hub_addr, &port_addr);
 
        hcd->hub_port[hub_addr] &= ~(1 << port_addr);
+#ifdef FIQ_DEBUG
        hcd->hub_port_alloc[hub_addr * 16 + port_addr] = -1;
-
+#endif
        fiq_print(FIQDBG_PORTHUB, "H%dP%d:RO%d", hub_addr, port_addr, DWC_CIRCLEQ_FIRST(&qh->qtd_list)->urb->pipe_info.ep_num);
 
 }
index d3d6e9976d30ec1d549e96869e54994730a10b9a..80a3af2f15c4a7531c62c0be0f81f6bbe8ef9bad 100644 (file)
@@ -577,8 +577,10 @@ struct dwc_otg_hcd {
        uint32_t *frame_list;
 
        /** Hub - Port assignment */
-       int hub_port[16];
-       int hub_port_alloc[256];
+       int hub_port[128];
+#ifdef FIQ_DEBUG
+       int hub_port_alloc[2048];
+#endif
 
        /** Frame List DMA address */
        dma_addr_t frame_list_dma;
index d6553634cd0cca56d4508d2879bc9daee8709045..1037a96667e6b9c236a75803fe903e16df91f10a 100644 (file)
@@ -1419,8 +1419,9 @@ cleanup:
                }
 
                hcd->hub_port[hc->hub_addr] &= ~(1 << hc->port_addr);
+#ifdef FIQ_DEBUG
                hcd->hub_port_alloc[hc->hub_addr * 16 + hc->port_addr] = -1;
-
+#endif
                fiq_print(FIQDBG_PORTHUB, "H%dP%d:RR%d", hc->hub_addr, hc->port_addr, endp);
        }