summaryrefslogtreecommitdiff
path: root/drivers/usb/gadget/function
diff options
context:
space:
mode:
authorMayank Rana <mrana@codeaurora.org>2015-09-02 16:25:31 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 19:58:21 -0700
commit4687a02e767fc1cc2f9275d6b7e3cb681a0d9945 (patch)
tree3993790d0cfa1fc055963bc57a182d960a04ea29 /drivers/usb/gadget/function
parentdf2968af9f8c4d3f784bd7a66a1adcfe9c9f743c (diff)
usb: u_data_bridge: Check allowable size with gbridge_port_write()
Currently gbridge_port_write() is not checking size of user space provided data and directly copies buffer into USB request buffer which is having size as 2KB. If user space application writes data bigger than 2KB, copy_from_user() tries to copy data beyond allocated USB request buffer size which results into memory corruption. Fix this issue by checking allowable size with gbridge_port_write() and making sure that it doesn't copy data beyond allocated buffer size. Change-Id: I7a34e37f5d1609792374f07b70542b80edbe6944 Signed-off-by: Mayank Rana <mrana@codeaurora.org>
Diffstat (limited to 'drivers/usb/gadget/function')
-rw-r--r--drivers/usb/gadget/function/u_data_bridge.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/usb/gadget/function/u_data_bridge.c b/drivers/usb/gadget/function/u_data_bridge.c
index 578c34e6687b..8a0ac837d66b 100644
--- a/drivers/usb/gadget/function/u_data_bridge.c
+++ b/drivers/usb/gadget/function/u_data_bridge.c
@@ -507,6 +507,7 @@ ssize_t gbridge_port_write(struct file *file,
struct gbridge_port *port;
struct usb_request *req;
struct list_head *pool;
+ unsigned xfer_size;
port = file->private_data;
if (!port) {
@@ -528,12 +529,17 @@ ssize_t gbridge_port_write(struct file *file,
spin_unlock_irqrestore(&port->port_lock, flags);
pr_debug("%s: write buf size:%zu\n", __func__, count);
- ret = copy_from_user(req->buf, buf, count);
+ if (count > BRIDGE_TX_BUF_SIZE)
+ xfer_size = BRIDGE_TX_BUF_SIZE;
+ else
+ xfer_size = count;
+
+ ret = copy_from_user(req->buf, buf, xfer_size);
if (ret) {
pr_err("copy_from_user failed: err %d\n", ret);
ret = -EFAULT;
} else {
- req->length = count;
+ req->length = xfer_size;
ret = usb_ep_queue(port->port_usb->in, req, GFP_KERNEL);
if (ret) {
pr_err("EP QUEUE failed:%d\n", ret);
@@ -552,7 +558,7 @@ err_exit:
if (ret)
return ret;
else
- return count;
+ return xfer_size;
}
static unsigned int gbridge_port_poll(struct file *file, poll_table *wait)