diff options
| author | Vijayavardhan Vennapusa <vvreddy@codeaurora.org> | 2016-07-21 15:00:49 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-01-19 21:14:58 -0800 |
| commit | c8023ef763c56210f62dbddcc16cf6275215dcf7 (patch) | |
| tree | 82caa898e6e00998531e00979ec56202a0732ed7 /drivers/usb/gadget/function | |
| parent | fdddc49ef25b6efe57e7a6e15b59dfb253dc496b (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.c | 13 |
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; |
