OSDN Git Service

USB: gadget: mass_storage: Fix Null pointer access during disconnect
authorVijayavardhan Vennapusa <vvreddy@codeaurora.org>
Thu, 10 Sep 2015 05:21:25 +0000 (10:51 +0530)
committerGerrit - the friendly Code Review server <code-review@localhost>
Fri, 20 Jan 2017 05:35:57 +0000 (21:35 -0800)
There is a chance that completion handler and ep disable race each other
and it might happen that completion handler gets called after driver_data
is set to NULL as part of function disable. This results in crash. Hence
add check in completion handler to check if driver_data is NULL or not
to fix the issue.

CRs-Fixed: 891650
Change-Id: I79ce3967533d2a7cb7591ccfe50b095a540e9884
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
drivers/usb/gadget/function/f_mass_storage.c

index f3715d8..9683a5e 100644 (file)
@@ -454,13 +454,23 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
        struct fsg_buffhd       *bh = req->context;
 
        if (req->status || req->actual != req->length)
-               DBG(common, "%s --> %d, %u/%u\n", __func__,
+               pr_debug("%s --> %d, %u/%u\n", __func__,
                    req->status, req->actual, req->length);
        if (req->status == -ECONNRESET)         /* Request was cancelled */
                usb_ep_fifo_flush(ep);
 
        /* Hold the lock while we update the request and buffer states */
        smp_wmb();
+       /*
+        * Disconnect and completion might race each other and driver data
+        * is set to NULL during ep disable. So, add a check if that is case.
+        */
+       if (!common) {
+               bh->inreq_busy = 0;
+               bh->state = BUF_STATE_EMPTY;
+               return;
+       }
+
        spin_lock(&common->lock);
        bh->inreq_busy = 0;
        bh->state = BUF_STATE_EMPTY;