Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: elan_i2c_smbus - fix more potential stack buffer overflows

Commit 40f7090bb1b4 ("Input: elan_i2c_smbus - fix corrupted stack")
fixed most of the functions using i2c_smbus_read_block_data() to
allocate a buffer with the maximum block size. However three
functions were left unchanged:

* In elan_smbus_initialize(), increase the buffer size in the same
way.
* In elan_smbus_calibrate_result(), the buffer is provided by the
caller (calibrate_store()), so introduce a bounce buffer. Also
name the result buffer size.
* In elan_smbus_get_report(), the buffer is provided by the caller
but happens to be the right length. Add a compile-time assertion
to ensure this remains the case.

Cc: <stable@vger.kernel.org> # 3.19+
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Reviewed-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Ben Hutchings and committed by
Dmitry Torokhov
50fc7b61 8938fc7b

+11 -3
+2
drivers/input/mouse/elan_i2c.h
··· 27 27 #define ETP_DISABLE_POWER 0x0001 28 28 #define ETP_PRESSURE_OFFSET 25 29 29 30 + #define ETP_CALIBRATE_MAX_LEN 3 31 + 30 32 /* IAP Firmware handling */ 31 33 #define ETP_PRODUCT_ID_FORMAT_STRING "%d.0" 32 34 #define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin"
+1 -1
drivers/input/mouse/elan_i2c_core.c
··· 613 613 int tries = 20; 614 614 int retval; 615 615 int error; 616 - u8 val[3]; 616 + u8 val[ETP_CALIBRATE_MAX_LEN]; 617 617 618 618 retval = mutex_lock_interruptible(&data->sysfs_mutex); 619 619 if (retval)
+8 -2
drivers/input/mouse/elan_i2c_smbus.c
··· 56 56 static int elan_smbus_initialize(struct i2c_client *client) 57 57 { 58 58 u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 }; 59 - u8 values[ETP_SMBUS_HELLOPACKET_LEN] = { 0, 0, 0, 0, 0 }; 59 + u8 values[I2C_SMBUS_BLOCK_MAX] = {0}; 60 60 int len, error; 61 61 62 62 /* Get hello packet */ ··· 117 117 static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) 118 118 { 119 119 int error; 120 + u8 buf[I2C_SMBUS_BLOCK_MAX] = {0}; 121 + 122 + BUILD_BUG_ON(ETP_CALIBRATE_MAX_LEN > sizeof(buf)); 120 123 121 124 error = i2c_smbus_read_block_data(client, 122 - ETP_SMBUS_CALIBRATE_QUERY, val); 125 + ETP_SMBUS_CALIBRATE_QUERY, buf); 123 126 if (error < 0) 124 127 return error; 125 128 129 + memcpy(val, buf, ETP_CALIBRATE_MAX_LEN); 126 130 return 0; 127 131 } 128 132 ··· 475 471 static int elan_smbus_get_report(struct i2c_client *client, u8 *report) 476 472 { 477 473 int len; 474 + 475 + BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN); 478 476 479 477 len = i2c_smbus_read_block_data(client, 480 478 ETP_SMBUS_PACKET_QUERY,