summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorHemant Kumar <hemantk@codeaurora.org>2016-05-02 11:09:00 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-10 15:14:12 -0700
commit9f9acf870f64fe5edeee8f76482568fbfe925bd4 (patch)
treef48ceda0dbfc4b5d81be852bc5f88070ed05fa1f /drivers/usb
parentff1259b38e88824ec1c8208091e475c55d6f8204 (diff)
usb: gadget: f_mtp: Fix issue of NULL pointer access in mtp_read
MTP usb device node created as a part of mtp function init call. Userspace can read/write to MTP device using this node. If MTP is not enabled in the composition and trying to read mtp_usb dev node from the userspace leading to null pointer access in mtp_read. Do not access ep OUT maxpacket size in mtp_read. First block on mtp_read until the state become online which doesn't wakeup from the thread and expecting for the read completion or state change which occurs as a part of set_alt. Change-Id: Icbee5fe7ae2c02b2bca185a0dc7587eb4940058a Signed-off-by: ChandanaKishori Chiluveru <cchilu@codeaurora.org> Signed-off-by: Azhar Shaikh <azhars@codeaurora.org> Signed-off-by: Hemant Kumar <hemantk@codeaurora.org>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/function/f_mtp.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/usb/gadget/function/f_mtp.c b/drivers/usb/gadget/function/f_mtp.c
index 6214f9a78845..269159a0fe9a 100644
--- a/drivers/usb/gadget/function/f_mtp.c
+++ b/drivers/usb/gadget/function/f_mtp.c
@@ -586,10 +586,6 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
DBG(cdev, "mtp_read(%zu)\n", count);
- len = ALIGN(count, dev->ep_out->maxpacket);
- if (len > mtp_rx_req_len)
- return -EINVAL;
-
/* we will block until we're online */
DBG(cdev, "mtp_read: waiting for online state\n");
ret = wait_event_interruptible(dev->read_wq,
@@ -598,6 +594,11 @@ static ssize_t mtp_read(struct file *fp, char __user *buf,
r = ret;
goto done;
}
+
+ len = ALIGN(count, dev->ep_out->maxpacket);
+ if (len > mtp_rx_req_len)
+ return -EINVAL;
+
spin_lock_irq(&dev->lock);
if (dev->state == STATE_CANCELED) {
/* report cancelation to userspace */