diff options
author | Ben Hutchings <ben.hutchings@codethink.co.uk> | 2018-06-19 14:17:32 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2018-06-21 20:20:41 -0400 |
commit | 50fc7b61959af4b95fafce7fe5dd565199e0b61a (patch) | |
tree | fe2962d4ef55cc1b49a52abbb8b913fff2ec1eb4 /drivers | |
parent | 8938fc7b8fe9ccfa11751ead502a8d385b607967 (diff) |
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>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/mouse/elan_i2c.h | 2 | ||||
-rw-r--r-- | drivers/input/mouse/elan_i2c_core.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/elan_i2c_smbus.c | 10 |
3 files changed, 11 insertions, 3 deletions
diff --git a/drivers/input/mouse/elan_i2c.h b/drivers/input/mouse/elan_i2c.h index 599544c1a91c..243e0fa6e3e3 100644 --- a/drivers/input/mouse/elan_i2c.h +++ b/drivers/input/mouse/elan_i2c.h | |||
@@ -27,6 +27,8 @@ | |||
27 | #define ETP_DISABLE_POWER 0x0001 | 27 | #define ETP_DISABLE_POWER 0x0001 |
28 | #define ETP_PRESSURE_OFFSET 25 | 28 | #define ETP_PRESSURE_OFFSET 25 |
29 | 29 | ||
30 | #define ETP_CALIBRATE_MAX_LEN 3 | ||
31 | |||
30 | /* IAP Firmware handling */ | 32 | /* IAP Firmware handling */ |
31 | #define ETP_PRODUCT_ID_FORMAT_STRING "%d.0" | 33 | #define ETP_PRODUCT_ID_FORMAT_STRING "%d.0" |
32 | #define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin" | 34 | #define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin" |
diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index f69d21610166..1f9cd7d8b7ad 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c | |||
@@ -613,7 +613,7 @@ static ssize_t calibrate_store(struct device *dev, | |||
613 | int tries = 20; | 613 | int tries = 20; |
614 | int retval; | 614 | int retval; |
615 | int error; | 615 | int error; |
616 | u8 val[3]; | 616 | u8 val[ETP_CALIBRATE_MAX_LEN]; |
617 | 617 | ||
618 | retval = mutex_lock_interruptible(&data->sysfs_mutex); | 618 | retval = mutex_lock_interruptible(&data->sysfs_mutex); |
619 | if (retval) | 619 | if (retval) |
diff --git a/drivers/input/mouse/elan_i2c_smbus.c b/drivers/input/mouse/elan_i2c_smbus.c index cfcb32559925..c060d270bc4d 100644 --- a/drivers/input/mouse/elan_i2c_smbus.c +++ b/drivers/input/mouse/elan_i2c_smbus.c | |||
@@ -56,7 +56,7 @@ | |||
56 | static int elan_smbus_initialize(struct i2c_client *client) | 56 | static int elan_smbus_initialize(struct i2c_client *client) |
57 | { | 57 | { |
58 | u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 }; | 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 | int len, error; | 60 | int len, error; |
61 | 61 | ||
62 | /* Get hello packet */ | 62 | /* Get hello packet */ |
@@ -117,12 +117,16 @@ static int elan_smbus_calibrate(struct i2c_client *client) | |||
117 | static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) | 117 | static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) |
118 | { | 118 | { |
119 | int error; | 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 | error = i2c_smbus_read_block_data(client, | 124 | error = i2c_smbus_read_block_data(client, |
122 | ETP_SMBUS_CALIBRATE_QUERY, val); | 125 | ETP_SMBUS_CALIBRATE_QUERY, buf); |
123 | if (error < 0) | 126 | if (error < 0) |
124 | return error; | 127 | return error; |
125 | 128 | ||
129 | memcpy(val, buf, ETP_CALIBRATE_MAX_LEN); | ||
126 | return 0; | 130 | return 0; |
127 | } | 131 | } |
128 | 132 | ||
@@ -472,6 +476,8 @@ static int elan_smbus_get_report(struct i2c_client *client, u8 *report) | |||
472 | { | 476 | { |
473 | int len; | 477 | int len; |
474 | 478 | ||
479 | BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN); | ||
480 | |||
475 | len = i2c_smbus_read_block_data(client, | 481 | len = i2c_smbus_read_block_data(client, |
476 | ETP_SMBUS_PACKET_QUERY, | 482 | ETP_SMBUS_PACKET_QUERY, |
477 | &report[ETP_SMBUS_REPORT_OFFSET]); | 483 | &report[ETP_SMBUS_REPORT_OFFSET]); |