From: Jianqiang Tang <jianqiang.t...@intel.com>

Do sanity check for usb request complete function as we hit random
null pointer kernel panic in giveback function.

>From the call trace, show the complete function should be null.
So we add the sanity check before every usb request queue to dwc3
also before dwc3 giveback the usb request.

Logs:
BUG: unable to handle kernel NULL pointer dereference at   (null)
IP: [<  (null)>]   (null)
Call Trace:
        ? dwc3_gadget_giveback+0xa5/0x130
        ? vsnprintf+0x166/0x3d0
        dwc3_remove_requests+0x57/0x70
        __dwc3_gadget_ep_disable+0x18/0x80
        dwc3_gadget_ep_disable+0x79/0x1a0
        linkwatch_fire_event+0x4c/0x90
        gether_disconnect+0x45/0x1b0
        ? wake_up_klogd+0x49/0x70
        console_unlock+0x295/0x4c0
        rndis_disable+0x3d/0x90
        preempt_count_add+0x55/0xa0
        reset_config+0x3b/0x90
        _raw_spin_lock_irqsave+0x25/0x30
        composite_disconnect+0x2f/0x50
        dwc3_gadget_disconnect_interrupt+0x62/0x90

Signed-off-by: Jianqiang Tang <jianqiang.t...@intel.com>
---
 drivers/usb/dwc3/gadget.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 2363bad..3c1ac95 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -268,7 +268,8 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, struct 
dwc3_request *req,
        trace_dwc3_gadget_giveback(req);
 
        spin_unlock(&dwc->lock);
-       usb_gadget_giveback_request(&dep->endpoint, &req->request);
+       if (req->request.complete)
+               usb_gadget_giveback_request(&dep->endpoint, &req->request);
        spin_lock(&dwc->lock);
 }
 
@@ -1233,6 +1234,16 @@ static int dwc3_gadget_ep_queue(struct usb_ep *ep, 
struct usb_request *request,
        int                             ret;
 
        spin_lock_irqsave(&dwc->lock, flags);
+
+       if (WARN(!request->complete, "request %p complete function is NULL\n",
+                               request)) {
+               dwc3_trace(trace_dwc3_gadget,
+                               "request %p complete function is NULL\n",
+                               request);
+               spin_unlock_irqrestore(&dwc->lock, flags);
+               return -EINVAL;
+       }
+
        ret = __dwc3_gadget_ep_queue(dep, req);
 
        /*
-- 
1.9.1

--
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