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 <felipe.ba...@linux.intel.com>
---
 drivers/usb/dwc3/gadget.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index f31a59cd5162..d9df5916efdb 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2019,6 +2019,14 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, 
struct dwc3_ep *dep,
                        break;
        } while (1);
 
+       /*
+        * Our endpoint might get disabled by another thread during
+        * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
+        * early on so DWC3_EP_BUSY flag gets cleared
+        */
+       if (!dep->endpoint.desc)
+               return 1;
+
        if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
                        list_empty(&dep->started_list)) {
                if (list_empty(&dep->pending_list)) {
@@ -2056,7 +2064,7 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 
*dwc,
                status = -ECONNRESET;
 
        clean_busy = dwc3_cleanup_done_reqs(dwc, dep, event, status);
-       if (clean_busy && (is_xfer_complete ||
+       if (clean_busy && (!dep->endpoint.desc || is_xfer_complete ||
                                usb_endpoint_xfer_isoc(dep->endpoint.desc)))
                dep->flags &= ~DWC3_EP_BUSY;
 
@@ -2085,6 +2093,14 @@ static void dwc3_endpoint_transfer_complete(struct dwc3 
*dwc,
                dwc->u1u2 = 0;
        }
 
+       /*
+        * Our endpoint might get disabled by another thread during
+        * dwc3_gadget_giveback(). If that happens, we're just gonna return 1
+        * early on so DWC3_EP_BUSY flag gets cleared
+        */
+       if (!dep->endpoint.desc)
+               return;
+
        if (!usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
                int ret;
 
-- 
2.8.3

---------------------------------------------------------------------
Intel Finland Oy
Registered Address: PL 281, 00181 Helsinki 
Business Identity Code: 0357606 - 4 
Domiciled in Helsinki 

This e-mail and any attachments may contain confidential material for
the sole use of the intended recipient(s). Any review or distribution
by others is strictly prohibited. If you are not the intended
recipient, please contact the sender and delete all copies.

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to