Skip to content

Commit 4cb4221

Browse files
author
Felipe Balbi
committed
usb: dwc3: gadget: fix for possible endpoint disable race
when we call dwc3_gadget_giveback(), we end up releasing our controller's lock. Another thread could get scheduled and disable the endpoint, subsequently setting dep->endpoint.desc to NULL. In that case, we would end up dereferencing a NULL pointer which would result in a Kernel Oops. Let's avoid the problem by simply returning early if we have a NULL descriptor. Signed-off-by: Felipe Balbi <[email protected]>
1 parent 9cad39f commit 4cb4221

File tree

1 file changed

+17
-1
lines changed

1 file changed

+17
-1
lines changed

drivers/usb/dwc3/gadget.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2041,6 +2041,14 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
20412041
break;
20422042
} while (1);
20432043

2044+
/*
2045+
* Our endpoint might get disabled by another thread during
2046+
* dwc3_gadget_giveback(). If that happens, we're just gonna return 1
2047+
* early on so DWC3_EP_BUSY flag gets cleared
2048+
*/
2049+
if (!dep->endpoint.desc)
2050+
return 1;
2051+
20442052
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
20452053
list_empty(&dep->started_list)) {
20462054
if (list_empty(&dep->pending_list)) {
@@ -2078,7 +2086,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
20782086
status = -ECONNRESET;
20792087

20802088
clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status);
2081-
if (clean_busy && (is_xfer_complete ||
2089+
if (clean_busy && (!dep->endpoint.desc || is_xfer_complete ||
20822090
usb_endpoint_xfer_isoc(dep->endpoint.desc)))
20832091
dep->flags &= ~DWC3_EP_BUSY;
20842092

@@ -2107,6 +2115,14 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 *dwc,
21072115
dwc->u1u2 = 0;
21082116
}
21092117

2118+
/*
2119+
* Our endpoint might get disabled by another thread during
2120+
* dwc3_gadget_giveback(). If that happens, we're just gonna return 1
2121+
* early on so DWC3_EP_BUSY flag gets cleared
2122+
*/
2123+
if (!dep->endpoint.desc)
2124+
return;
2125+
21102126
if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
21112127
int ret;
21122128

0 commit comments

Comments
 (0)