Jelajahi Sumber

Input: elan_i2c - verify firmware signature applying it

To allow for different firmware sizes let's replace the original size check
with with checking the signature in the firmware data.

Signed-off-by: Duson Lin <dusonlin@emc.com.tw>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Duson Lin 10 tahun lalu
induk
melakukan
bb03bf3f84

+ 3 - 3
drivers/input/mouse/elan_i2c.h

@@ -4,7 +4,6 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.5.5
  *
  *
  * Based on cyapa driver:
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -33,8 +32,9 @@
 #define ETP_FW_IAP_PAGE_ERR	(1 << 5)
 #define ETP_FW_IAP_PAGE_ERR	(1 << 5)
 #define ETP_FW_IAP_INTF_ERR	(1 << 4)
 #define ETP_FW_IAP_INTF_ERR	(1 << 4)
 #define ETP_FW_PAGE_SIZE	64
 #define ETP_FW_PAGE_SIZE	64
-#define ETP_FW_PAGE_COUNT	768
-#define ETP_FW_SIZE		(ETP_FW_PAGE_SIZE * ETP_FW_PAGE_COUNT)
+#define ETP_FW_VAILDPAGE_COUNT	768
+#define ETP_FW_SIGNATURE_SIZE	6
+#define ETP_FW_SIGNATURE_ADDRESS	0xBFFA
 
 
 struct i2c_client;
 struct i2c_client;
 struct completion;
 struct completion;

+ 12 - 9
drivers/input/mouse/elan_i2c_core.c

@@ -4,7 +4,7 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.5.5
+ * Version: 1.5.6
  *
  *
  * Based on cyapa driver:
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
@@ -40,7 +40,7 @@
 #include "elan_i2c.h"
 #include "elan_i2c.h"
 
 
 #define DRIVER_NAME		"elan_i2c"
 #define DRIVER_NAME		"elan_i2c"
-#define ELAN_DRIVER_VERSION	"1.5.5"
+#define ELAN_DRIVER_VERSION	"1.5.6"
 #define ETP_PRESSURE_OFFSET	25
 #define ETP_PRESSURE_OFFSET	25
 #define ETP_MAX_PRESSURE	255
 #define ETP_MAX_PRESSURE	255
 #define ETP_FWIDTH_REDUCE	90
 #define ETP_FWIDTH_REDUCE	90
@@ -312,7 +312,7 @@ static int __elan_update_firmware(struct elan_tp_data *data,
 	iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
 	iap_start_addr = get_unaligned_le16(&fw->data[ETP_IAP_START_ADDR * 2]);
 
 
 	boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE;
 	boot_page_count = (iap_start_addr * 2) / ETP_FW_PAGE_SIZE;
-	for (i = boot_page_count; i < ETP_FW_PAGE_COUNT; i++) {
+	for (i = boot_page_count; i < ETP_FW_VAILDPAGE_COUNT; i++) {
 		u16 checksum = 0;
 		u16 checksum = 0;
 		const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
 		const u8 *page = &fw->data[i * ETP_FW_PAGE_SIZE];
 
 
@@ -434,10 +434,11 @@ static ssize_t elan_sysfs_update_fw(struct device *dev,
 				    struct device_attribute *attr,
 				    struct device_attribute *attr,
 				    const char *buf, size_t count)
 				    const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct elan_tp_data *data = i2c_get_clientdata(client);
+	struct elan_tp_data *data = dev_get_drvdata(dev);
 	const struct firmware *fw;
 	const struct firmware *fw;
 	int error;
 	int error;
+	const u8 *fw_signature;
+	static const u8 signature[] = {0xAA, 0x55, 0xCC, 0x33, 0xFF, 0xFF};
 
 
 	error = request_firmware(&fw, ETP_FW_NAME, dev);
 	error = request_firmware(&fw, ETP_FW_NAME, dev);
 	if (error) {
 	if (error) {
@@ -446,10 +447,12 @@ static ssize_t elan_sysfs_update_fw(struct device *dev,
 		return error;
 		return error;
 	}
 	}
 
 
-	/* Firmware must be exactly PAGE_NUM * PAGE_SIZE bytes */
-	if (fw->size != ETP_FW_SIZE) {
-		dev_err(dev, "invalid firmware size = %zu, expected %d.\n",
-			fw->size, ETP_FW_SIZE);
+	/* Firmware file must match signature data */
+	fw_signature = &fw->data[ETP_FW_SIGNATURE_ADDRESS];
+	if (memcmp(fw_signature, signature, sizeof(signature)) != 0) {
+		dev_err(dev, "signature mismatch (expected %*ph, got %*ph)\n",
+			(int)sizeof(signature), signature,
+			(int)sizeof(signature), fw_signature);
 		error = -EBADF;
 		error = -EBADF;
 		goto out_release_fw;
 		goto out_release_fw;
 	}
 	}

+ 0 - 1
drivers/input/mouse/elan_i2c_i2c.c

@@ -4,7 +4,6 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.5.5
  *
  *
  * Based on cyapa driver:
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.

+ 0 - 1
drivers/input/mouse/elan_i2c_smbus.c

@@ -4,7 +4,6 @@
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  * Copyright (c) 2013 ELAN Microelectronics Corp.
  *
  *
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
  * Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
- * Version: 1.5.5
  *
  *
  * Based on cyapa driver:
  * Based on cyapa driver:
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.
  * copyright (c) 2011-2012 Cypress Semiconductor, Inc.