Commit 50fc7b61 authored by Ben Hutchings's avatar Ben Hutchings Committed by Dmitry Torokhov

Input: elan_i2c_smbus - fix more potential stack buffer overflows

Commit 40f7090b ("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: default avatarBen Hutchings <ben.hutchings@codethink.co.uk>
Reviewed-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarDmitry Torokhov <dmitry.torokhov@gmail.com>
parent 8938fc7b
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#define ETP_DISABLE_POWER 0x0001 #define ETP_DISABLE_POWER 0x0001
#define ETP_PRESSURE_OFFSET 25 #define ETP_PRESSURE_OFFSET 25
#define ETP_CALIBRATE_MAX_LEN 3
/* IAP Firmware handling */ /* IAP Firmware handling */
#define ETP_PRODUCT_ID_FORMAT_STRING "%d.0" #define ETP_PRODUCT_ID_FORMAT_STRING "%d.0"
#define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin" #define ETP_FW_NAME "elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin"
......
...@@ -613,7 +613,7 @@ static ssize_t calibrate_store(struct device *dev, ...@@ -613,7 +613,7 @@ static ssize_t calibrate_store(struct device *dev,
int tries = 20; int tries = 20;
int retval; int retval;
int error; int error;
u8 val[3]; u8 val[ETP_CALIBRATE_MAX_LEN];
retval = mutex_lock_interruptible(&data->sysfs_mutex); retval = mutex_lock_interruptible(&data->sysfs_mutex);
if (retval) if (retval)
......
...@@ -56,7 +56,7 @@ ...@@ -56,7 +56,7 @@
static int elan_smbus_initialize(struct i2c_client *client) static int elan_smbus_initialize(struct i2c_client *client)
{ {
u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 }; u8 check[ETP_SMBUS_HELLOPACKET_LEN] = { 0x55, 0x55, 0x55, 0x55, 0x55 };
u8 values[ETP_SMBUS_HELLOPACKET_LEN] = { 0, 0, 0, 0, 0 }; u8 values[I2C_SMBUS_BLOCK_MAX] = {0};
int len, error; int len, error;
/* Get hello packet */ /* Get hello packet */
...@@ -117,12 +117,16 @@ static int elan_smbus_calibrate(struct i2c_client *client) ...@@ -117,12 +117,16 @@ static int elan_smbus_calibrate(struct i2c_client *client)
static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val) static int elan_smbus_calibrate_result(struct i2c_client *client, u8 *val)
{ {
int error; int error;
u8 buf[I2C_SMBUS_BLOCK_MAX] = {0};
BUILD_BUG_ON(ETP_CALIBRATE_MAX_LEN > sizeof(buf));
error = i2c_smbus_read_block_data(client, error = i2c_smbus_read_block_data(client,
ETP_SMBUS_CALIBRATE_QUERY, val); ETP_SMBUS_CALIBRATE_QUERY, buf);
if (error < 0) if (error < 0)
return error; return error;
memcpy(val, buf, ETP_CALIBRATE_MAX_LEN);
return 0; return 0;
} }
...@@ -472,6 +476,8 @@ static int elan_smbus_get_report(struct i2c_client *client, u8 *report) ...@@ -472,6 +476,8 @@ static int elan_smbus_get_report(struct i2c_client *client, u8 *report)
{ {
int len; int len;
BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN);
len = i2c_smbus_read_block_data(client, len = i2c_smbus_read_block_data(client,
ETP_SMBUS_PACKET_QUERY, ETP_SMBUS_PACKET_QUERY,
&report[ETP_SMBUS_REPORT_OFFSET]); &report[ETP_SMBUS_REPORT_OFFSET]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment