From 8a950b2d64cec7b8022b7572c2d3d9221b2dbab2 Mon Sep 17 00:00:00 2001 From: Min Chong Date: Thu, 13 Oct 2016 09:53:23 -0700 Subject: [PATCH] input: synaptics_dsx: add bounds checks for firmware id A series of characters between '0' and '9' with a length more than MAX_FIRMWARE_ID_LEN causes a heap buffer overflow. This is mitigated by performing a bounds check. Bug: 31911920 Signed-off-by: Mark Salyzyn Signed-off-by: Min Chong Change-Id: Iaefe92df2610153f2d3e2caa58322ae82cb5b7c2 --- .../synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c index af6f92553aa7e..05f13b427739b 100644 --- a/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c +++ b/drivers/input/touchscreen/synaptics_dsx_htc_2.6/synaptics_dsx_fw_update.c @@ -30,7 +30,7 @@ * TOTAL CUMULATIVE LIABILITY TO ANY PARTY SHALL NOT EXCEED ONE HUNDRED U.S. * DOLLARS. */ - +#include #include #include #include @@ -2508,15 +2508,15 @@ static int fwu_read_f34_blocks(unsigned short block_cnt, unsigned char cmd) static int fwu_get_image_firmware_id(unsigned int *fw_id) { int retval; - unsigned char index = 0; - char *strptr; char *firmware_id; struct synaptics_rmi4_data *rmi4_data = fwu->rmi4_data; if (fwu->img.contains_firmware_id) { *fw_id = fwu->img.firmware_id; } else { - strptr = strnstr(fwu->image_name, "PR", MAX_IMAGE_NAME_LEN); + size_t index, max_index; + unsigned char *strptr = strnstr(fwu->image_name, "PR", MAX_IMAGE_NAME_LEN); + if (!strptr) { dev_err(rmi4_data->pdev->dev.parent, "%s: No valid PR number (PRxxxxxxx) found in image file name (%s)\n", @@ -2532,7 +2532,11 @@ static int fwu_get_image_firmware_id(unsigned int *fw_id) __func__); return -ENOMEM; } - while (strptr[index] >= '0' && strptr[index] <= '9') { + + max_index = min((ptrdiff_t)(MAX_FIRMWARE_ID_LEN - 1), + &fwu->image_name[MAX_IMAGE_NAME_LEN] - strptr); + index = 0; + while (index < max_index && isdigit(strptr[index])) { firmware_id[index] = strptr[index]; index++; }