From bb03bf3f8427a38112819061fc8688999ba02f67 Mon Sep 17 00:00:00 2001 From: Duson Lin Date: Fri, 23 Jan 2015 09:35:07 -0800 Subject: 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 Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/elan_i2c_core.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'drivers/input/mouse/elan_i2c_core.c') diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index 0cb2be48d537..7ce8bfe22d7e 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -4,7 +4,7 @@ * Copyright (c) 2013 ELAN Microelectronics Corp. * * Author: 林政維 (Duson Lin) - * Version: 1.5.5 + * Version: 1.5.6 * * Based on cyapa driver: * copyright (c) 2011-2012 Cypress Semiconductor, Inc. @@ -40,7 +40,7 @@ #include "elan_i2c.h" #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_MAX_PRESSURE 255 #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]); 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; 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, 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; int error; + const u8 *fw_signature; + static const u8 signature[] = {0xAA, 0x55, 0xCC, 0x33, 0xFF, 0xFF}; error = request_firmware(&fw, ETP_FW_NAME, dev); if (error) { @@ -446,10 +447,12 @@ static ssize_t elan_sysfs_update_fw(struct device *dev, 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; goto out_release_fw; } -- cgit v1.2.3