Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#define ETP_DISABLE_POWER	0x0001
#define ETP_PRESSURE_OFFSET	25

#define ETP_CALIBRATE_MAX_LEN	3

/* IAP Firmware handling */
#define ETP_PRODUCT_ID_FORMAT_STRING	"%d.0"
#define ETP_FW_NAME		"elan_i2c_" ETP_PRODUCT_ID_FORMAT_STRING ".bin"
+1 −1
Original line number Diff line number Diff line
@@ -613,7 +613,7 @@ static ssize_t calibrate_store(struct device *dev,
	int tries = 20;
	int retval;
	int error;
	u8 val[3];
	u8 val[ETP_CALIBRATE_MAX_LEN];

	retval = mutex_lock_interruptible(&data->sysfs_mutex);
	if (retval)
+8 −2
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@
static int elan_smbus_initialize(struct i2c_client *client)
{
	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;

	/* Get hello packet */
@@ -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)
{
	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,
					  ETP_SMBUS_CALIBRATE_QUERY, val);
					  ETP_SMBUS_CALIBRATE_QUERY, buf);
	if (error < 0)
		return error;

	memcpy(val, buf, ETP_CALIBRATE_MAX_LEN);
	return 0;
}

@@ -472,6 +476,8 @@ static int elan_smbus_get_report(struct i2c_client *client, u8 *report)
{
	int len;

	BUILD_BUG_ON(I2C_SMBUS_BLOCK_MAX > ETP_SMBUS_REPORT_LEN);

	len = i2c_smbus_read_block_data(client,
					ETP_SMBUS_PACKET_QUERY,
					&report[ETP_SMBUS_REPORT_OFFSET]);