DivestOS/Patches/Linux_CVEs/CVE-2016-3865/0.patch

87 lines
2.7 KiB
Diff

From a92e71c20f4e6b2aa94b7614fd494833ea76b8b9 Mon Sep 17 00:00:00 2001
From: Biswajit Paul <biswajitpaul@codeaurora.org>
Date: Thu, 30 Jun 2016 19:00:50 -0700
Subject: [PATCH] input: synaptics: allocate heap memory for temp buf
rmidev file operations structure include write() and
read() which accepts data from user space. Temp
buffers are allocated through variable length arrays
which can pose security problems. So allocate memory
on heap instead of stack to avoid this.
Bug: 28799389
CRs-Fixed: 1032459
Change-Id: I44443f91d435715dd0097ef8e8dfc48e291f93fc
Signed-off-by: Mohan Pallaka <mpallaka@codeaurora.org>
Signed-off-by: Biswajit Paul <biswajitpaul@codeaurora.org>
---
drivers/input/touchscreen/synaptics_rmi_dev.c | 19 +++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)
diff --git a/drivers/input/touchscreen/synaptics_rmi_dev.c b/drivers/input/touchscreen/synaptics_rmi_dev.c
index 88595582579e0..e2d7c27eb6832 100644
--- a/drivers/input/touchscreen/synaptics_rmi_dev.c
+++ b/drivers/input/touchscreen/synaptics_rmi_dev.c
@@ -291,7 +291,7 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf,
size_t count, loff_t *f_pos)
{
ssize_t retval;
- unsigned char tmpbuf[count + 1];
+ unsigned char *tmpbuf;
struct rmidev_data *dev_data = filp->private_data;
if (IS_ERR(dev_data)) {
@@ -305,6 +305,10 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf,
if (count > (REG_ADDR_LIMIT - *f_pos))
count = REG_ADDR_LIMIT - *f_pos;
+ tmpbuf = kzalloc(count + 1, GFP_KERNEL);
+ if (!tmpbuf)
+ return -ENOMEM;
+
mutex_lock(&(dev_data->file_mutex));
retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
@@ -322,6 +326,7 @@ static ssize_t rmidev_read(struct file *filp, char __user *buf,
clean_up:
mutex_unlock(&(dev_data->file_mutex));
+ kfree(tmpbuf);
return retval;
}
@@ -337,7 +342,7 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf,
size_t count, loff_t *f_pos)
{
ssize_t retval;
- unsigned char tmpbuf[count + 1];
+ unsigned char *tmpbuf;
struct rmidev_data *dev_data = filp->private_data;
if (IS_ERR(dev_data)) {
@@ -351,8 +356,14 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf,
if (count > (REG_ADDR_LIMIT - *f_pos))
count = REG_ADDR_LIMIT - *f_pos;
- if (copy_from_user(tmpbuf, buf, count))
+ tmpbuf = kzalloc(count + 1, GFP_KERNEL);
+ if (!tmpbuf)
+ return -ENOMEM;
+
+ if (copy_from_user(tmpbuf, buf, count)) {
+ kfree(tmpbuf);
return -EFAULT;
+ }
mutex_lock(&(dev_data->file_mutex));
@@ -364,7 +375,7 @@ static ssize_t rmidev_write(struct file *filp, const char __user *buf,
*f_pos += retval;
mutex_unlock(&(dev_data->file_mutex));
-
+ kfree(tmpbuf);
return retval;
}