USB: f_fs: Fix epfile crash during composition switch

epfile's ep pointer may be NULL during adb transfer
and composition switch happening in parallel. As part
of composition switch, first it is set to NONE. Setting
sys.usb.config to NONE stops adb and disables the composition.
stop adb is not blocking call and adb still might be doing
epfile read/write for some time when function unbind is
ongoing making the data structures NULL.

To fix this crash, call usb_ep_dequeue only if ep->ep is
valid. Similarly in success case, return ep->status only
if ep->ep is valid otherwise return -ENODEV.

Change-Id: Ic152fc1db31cad6f97b8d16d91350dad857a4bf9
Signed-off-by: Sujeet Kumar <ksujeet@codeaurora.org>
Signed-off-by: Mayank Rana <mrana@codeaurora.org>
This commit is contained in:
Sujeet Kumar 2016-01-28 10:27:44 -08:00 committed by David Keitel
parent 61c08e8af6
commit 8b5f119fba

View file

@ -833,8 +833,11 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
/* nop */
} else if (unlikely(
wait_for_completion_interruptible(&done))) {
ret = -EINTR;
spin_lock_irq(&epfile->ffs->eps_lock);
if (ep->ep)
usb_ep_dequeue(ep->ep, req);
spin_unlock_irq(&epfile->ffs->eps_lock);
ret = -EINTR;
} else {
/*
* XXX We may end up silently droping data
@ -843,7 +846,12 @@ static ssize_t ffs_epfile_io(struct file *file, struct ffs_io_data *io_data)
* to maxpacketsize), we may end up with more
* data then user space has space for.
*/
spin_lock_irq(&epfile->ffs->eps_lock);
if (ep->ep)
ret = ep->status;
else
ret = -ENODEV;
spin_unlock_irq(&epfile->ffs->eps_lock);
if (io_data->read && ret > 0) {
ret = copy_to_iter(data, ret, &io_data->data);
if (!ret)