input: synaptics_dsx: validate 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: I22f5b67815fe7d448b5ed847e4e3d65af63bed84
Signed-off-by: Andrew Chant <achant@google.com>
Git-repo: https://android.googlesource.com/kernel/msm
Git-commit: 271baca849983ef309e82a4e5953027790f36154
Signed-off-by: Dennis Cagle <dcagle@codeaurora.org>
Signed-off-by: Shantanu Jain <shjain@qti.qualcomm.com>
This commit is contained in:
Andrew Chant 2017-04-07 10:58:26 -07:00 committed by Gerrit - the friendly Code Review server
parent 0530e3fe60
commit 85eadde1c4

View file

@ -1495,7 +1495,7 @@ static int synaptics_rmi4_irq_enable(struct synaptics_rmi4_data *rmi4_data,
return retval; return retval;
} }
static void synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler, static int synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler,
struct synaptics_rmi4_fn_desc *fd, struct synaptics_rmi4_fn_desc *fd,
unsigned int intr_count) unsigned int intr_count)
{ {
@ -1503,6 +1503,12 @@ static void synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler,
unsigned char intr_offset; unsigned char intr_offset;
fhandler->intr_reg_num = (intr_count + 7) / 8; 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) if (fhandler->intr_reg_num != 0)
fhandler->intr_reg_num -= 1; fhandler->intr_reg_num -= 1;
@ -1515,7 +1521,7 @@ static void synaptics_rmi4_set_intr_mask(struct synaptics_rmi4_fn *fhandler,
ii++) ii++)
fhandler->intr_mask |= 1 << ii; fhandler->intr_mask |= 1 << ii;
return; return 0;
} }
static int synaptics_rmi4_f01_init(struct synaptics_rmi4_data *rmi4_data, static int synaptics_rmi4_f01_init(struct synaptics_rmi4_data *rmi4_data,
@ -1523,12 +1529,17 @@ static int synaptics_rmi4_f01_init(struct synaptics_rmi4_data *rmi4_data,
struct synaptics_rmi4_fn_desc *fd, struct synaptics_rmi4_fn_desc *fd,
unsigned int intr_count) unsigned int intr_count)
{ {
int retval;
fhandler->fn_number = fd->fn_number; fhandler->fn_number = fd->fn_number;
fhandler->num_of_data_sources = fd->intr_src_count; fhandler->num_of_data_sources = fd->intr_src_count;
fhandler->data = NULL; fhandler->data = NULL;
fhandler->extra = 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_query_base_addr = fd->query_base_addr;
rmi4_data->f01_ctrl_base_addr = fd->ctrl_base_addr; rmi4_data->f01_ctrl_base_addr = fd->ctrl_base_addr;
@ -1653,7 +1664,9 @@ static int synaptics_rmi4_f11_init(struct synaptics_rmi4_data *rmi4_data,
if (retval < 0) if (retval < 0)
return retval; 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;
abs_data_size = query[5] & MASK_2BIT; abs_data_size = query[5] & MASK_2BIT;
abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0)); abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0));
@ -1934,7 +1947,9 @@ static int synaptics_rmi4_f12_init(struct synaptics_rmi4_data *rmi4_data,
if (retval < 0) if (retval < 0)
goto free_function_handler_mem; goto free_function_handler_mem;
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 */ /* Allocate memory for finger data storage space */
fhandler->data_size = num_of_fingers * size_of_2d_data; fhandler->data_size = num_of_fingers * size_of_2d_data;
@ -2092,7 +2107,9 @@ static int synaptics_rmi4_f1a_init(struct synaptics_rmi4_data *rmi4_data,
fhandler->fn_number = fd->fn_number; fhandler->fn_number = fd->fn_number;
fhandler->num_of_data_sources = fd->intr_src_count; 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); retval = synaptics_rmi4_f1a_alloc_mem(rmi4_data, fhandler);
if (retval < 0) if (retval < 0)
@ -2491,6 +2508,8 @@ flash_prog_mode:
dev_dbg(rmi4_data->pdev->dev.parent, dev_dbg(rmi4_data->pdev->dev.parent,
"%s: Number of interrupt registers = %d\n", "%s: Number of interrupt registers = %d\n",
__func__, rmi4_data->num_of_intr_regs); __func__, rmi4_data->num_of_intr_regs);
if (rmi4_data->num_of_intr_regs >= MAX_INTR_REGISTERS)
return -EINVAL;
retval = synaptics_rmi4_reg_read(rmi4_data, retval = synaptics_rmi4_reg_read(rmi4_data,
rmi4_data->f01_query_base_addr, rmi4_data->f01_query_base_addr,