summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function
diff options
context:
space:
mode:
authorVijayavardhan Vennapusa <vvreddy@codeaurora.org>2016-07-21 15:00:49 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-01-19 21:14:58 -0800
commitc8023ef763c56210f62dbddcc16cf6275215dcf7 (patch)
tree82caa898e6e00998531e00979ec56202a0732ed7 /drivers/usb/gadget/function
parentfdddc49ef25b6efe57e7a6e15b59dfb253dc496b (diff)
USB: gadget: mass_storage: Fix Null pointer access during disconnect
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. Change-Id: I3496811f52af79e8dccb701b2753a81f5d5a2340 Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
Diffstat (limited to 'drivers/usb/gadget/function')
-rw-r--r--drivers/usb/gadget/function/f_mass_storage.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index f3715d85aedc..0a5003ffb621 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -473,15 +473,24 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
struct fsg_common *common = ep->driver_data;
struct fsg_buffhd *bh = req->context;
- dump_msg(common, "bulk-out", req->buf, req->actual);
if (req->status || req->actual != bh->bulk_out_intended_length)
- DBG(common, "%s --> %d, %u/%u\n", __func__,
+ pr_debug("%s --> %d, %u/%u\n", __func__,
req->status, req->actual, bh->bulk_out_intended_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->outreq_busy = 0;
+ return;
+ }
+
+ dump_msg(common, "bulk-out", req->buf, req->actual);
spin_lock(&common->lock);
bh->outreq_busy = 0;
bh->state = BUF_STATE_FULL;