DivestOS/Patches/Linux_CVEs/CVE-2017-0650/ANY/0001.patch
2017-11-07 17:32:46 -05:00

155 lines
5.3 KiB
Diff

From c6d874fd2c515406bc33ab78d60df70a47bddae2 Mon Sep 17 00:00:00 2001
From: Andrew Chant <achant@google.com>
Date: Fri, 7 Apr 2017 10:42:31 -0700
Subject: [PATCH] input: synaptics_dsx: valid bounds of intr_reg_num
Validate the intr_reg_num value returned by touchscreen
to ensure no out of bounds access can occur.
Bug: 35472278
Change-Id: If98e7091bf938061ac1b473ec652a620f118dbf0
Signed-off-by: Andrew Chant <achant@google.com>
---
.../synaptics_dsx_htc_2.6/synaptics_dsx_core.c | 50 ++++++++++++++++------
1 file changed, 38 insertions(+), 12 deletions(-)
diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_core.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_core.c
index 90b6fc37284b7..dbe242808841b 100644
--- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_core.c
+++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_core.c
@@ -2460,14 +2460,20 @@ static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
return retval;
}
-static void synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler,
- struct synaptics_rmi4_fn_desc *fd,
- unsigned int intr_count)
+static int synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler,
+ struct synaptics_rmi4_fn_desc *fd,
+ unsigned int intr_count)
{
unsigned char ii;
unsigned char intr_offset;
fhandler->intr_reg_num = (intr_count + 7) / 8;
+ if (fhandler->intr_reg_num >= MAX_INTR_REGISTERS) {
+ fhandler->intr_reg_num = 0;
+ fhandler->num_of_data_sources = 0;
+ fhandler->intr_mask = 0;
+ return -EINVAL;
+ }
if (fhandler->intr_reg_num != 0)
fhandler->intr_reg_num -= 1;
@@ -2479,7 +2485,7 @@ static void synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler,
ii++)
fhandler->intr_mask |= 1 << ii;
- return;
+ return 0;
}
static int synaptics_rmi4_f01_init(struct synaptics_rmi4_data *rmi4_data,
@@ -2487,12 +2493,16 @@ static int synaptics_rmi4_f01_init(struct synaptics_rmi4_data *rmi4_data,
struct synaptics_rmi4_fn_desc *fd,
unsigned int intr_count)
{
+ int retval;
+
fhandler->fn_number = fd->fn_number;
fhandler->num_of_data_sources = fd->intr_src_count;
fhandler->data = NULL;
fhandler->extra = NULL;
- synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ retval = synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ if (retval < 0)
+ return retval;
rmi4_data->f01_query_base_addr = fd->query_base_addr;
rmi4_data->f01_ctrl_base_addr = fd->ctrl_base_addr;
@@ -2578,7 +2588,9 @@ static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data,
rmi4_data->sensor_max_y = temp;
}
- synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ retval = synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ if (retval < 0)
+ return retval;
fhandler->data = NULL;
@@ -3362,7 +3374,9 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,
return retval;
}
- synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ retval = synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ if (retval < 0)
+ return retval;
/* Allocate memory for finger data storage space */
fhandler->data_size = num_of_fingers * size_of_2d_data;
@@ -3569,7 +3583,9 @@ static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data,
fhandler->fn_number = fd->fn_number;
fhandler->num_of_data_sources = fd->intr_src_count;
- synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ retval = synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ if (retval < 0)
+ return retval;
retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler);
if (retval < 0)
@@ -3596,12 +3612,16 @@ static int synaptics_rmi4_f34_init(struct synaptics_rmi4_data *rmi4_data,
unsigned int intr_count,
unsigned int page_number)
{
+ int retval;
+
fhandler->fn_number = fd->fn_number;
fhandler->num_of_data_sources = fd->intr_src_count;
fhandler->data = NULL;
fhandler->extra = NULL;
- synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ retval = synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ if (retval < 0)
+ return retval;
rmi4_data->f34_query_base_addr =
(fd->query_base_addr | (page_number << 8));
@@ -3634,7 +3654,9 @@ static int synaptics_rmi4_f54_init(struct synaptics_rmi4_data *rmi4_data,
fhandler->data = NULL;
fhandler->extra = NULL;
- synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ retval = synaptics_rmi4_set_intr_mask(fhandler, fd, intr_count);
+ if (retval < 0)
+ return retval;
rmi4_data->f54_query_base_addr =
(fd->query_base_addr | (page_number << 8));
@@ -4127,8 +4149,10 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
fhandler->fn_number = rmi_fd.fn_number;
fhandler->num_of_data_sources =
rmi_fd.intr_src_count;
- synaptics_rmi4_set_intr_mask(fhandler, &rmi_fd,
- intr_count);
+ retval = synaptics_rmi4_set_intr_mask(
+ fhandler, &rmi_fd, intr_count);
+ if (retval < 0)
+ return retval;
#endif
#ifdef F51_DISCRETE_FORCE
@@ -4171,6 +4195,8 @@ static int synaptics_rmi4_query_device(struct synaptics_rmi4_data *rmi4_data)
dev_dbg(rmi4_data->pdev->dev.parent,
"%s: Number of interrupt registers = %d\n",
__func__, rmi4_data->num_of_intr_regs);
+ if (rmi4_data->num_of_intr_regs > MAX_INTR_REGISTERS)
+ return -EINVAL;
f01_query = kmalloc(F01_STD_QUERY_LEN, GFP_KERNEL);
if (!f01_query) {