From: lyz Date: Thu, 19 Jun 2014 03:42:25 +0000 (+0800) Subject: usb: dwc_otg hcd driver: fix a race condition X-Git-Tag: firefly_0821_release~5069 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=036f439338d3e8285786c977a56b9a7cf3226965;p=firefly-linux-kernel-4.4.55.git usb: dwc_otg hcd driver: fix a race condition When pannic occurs, PC is at dwc_otg_hcd_urb_enqueue+0x118/0x184 LR is at dwc_otg_hcd_urb_enqueue+0xf4/0x184 There may be more than one threads running function dwc_otg_hcd_urb_enqueue().So we should use a spinlock to protect the dwc_otg_qh_t struct against a use-after-free bug. --- diff --git a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c index 30a8bf1fa32c..e8b0ef56913f 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_hcd.c @@ -513,12 +513,11 @@ int dwc_otg_hcd_urb_enqueue(dwc_otg_hcd_t *hcd, DWC_ERROR("DWC OTG HCD URB Enqueue failed creating QTD\n"); return -DWC_E_NO_MEMORY; } - + DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); retval = dwc_otg_hcd_qtd_add(qtd, hcd, (dwc_otg_qh_t **) ep_handle, atomic_alloc); - DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); if (retval < 0) { DWC_ERROR("DWC OTG HCD URB Enqueue failed adding QTD. " "Error status %d\n", retval); diff --git a/drivers/usb/dwc_otg_310/dwc_otg_hcd_queue.c b/drivers/usb/dwc_otg_310/dwc_otg_hcd_queue.c index 04661ce09852..faa7327943e6 100755 --- a/drivers/usb/dwc_otg_310/dwc_otg_hcd_queue.c +++ b/drivers/usb/dwc_otg_310/dwc_otg_hcd_queue.c @@ -703,7 +703,6 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *qtd, int atomic_alloc) { int retval = 0; - dwc_irqflags_t flags; dwc_otg_hcd_urb_t *urb = qtd->urb; @@ -719,13 +718,11 @@ int dwc_otg_hcd_qtd_add(dwc_otg_qtd_t *qtd, } } qtd->qh = *qh; - DWC_SPINLOCK_IRQSAVE(hcd->lock, &flags); retval = dwc_otg_hcd_qh_add(hcd, *qh); if (retval == 0) { DWC_CIRCLEQ_INSERT_TAIL(&((*qh)->qtd_list), qtd, qtd_list_entry); } - DWC_SPINUNLOCK_IRQRESTORE(hcd->lock, flags); done: