aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2018-07-27 14:46:46 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2018-07-27 14:59:32 -0400
commita4891f10583748933a9985fac7aa7c073cc59c85 (patch)
treecddd2e3676e8b4d73a3013dc83cd729b4970ce86 /drivers/input
parentf865df7364c3be0aa1e6f708d246af97c134893f (diff)
Input: atmel_mxt_ts - zero terminate config firmware file
We use sscanf to parse the configuration file, so it's necessary to zero terminate the configuration otherwise a truncated file can cause the parser to run off into uninitialised memory. Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 0ce126e918f1..77387f896262 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -279,7 +279,7 @@ enum mxt_suspend_mode {
279 279
280/* Config update context */ 280/* Config update context */
281struct mxt_cfg { 281struct mxt_cfg {
282 const u8 *raw; 282 u8 *raw;
283 size_t raw_size; 283 size_t raw_size;
284 off_t raw_pos; 284 off_t raw_pos;
285 285
@@ -1451,14 +1451,19 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
1451 u32 info_crc, config_crc, calculated_crc; 1451 u32 info_crc, config_crc, calculated_crc;
1452 u16 crc_start = 0; 1452 u16 crc_start = 0;
1453 1453
1454 cfg.raw = fw->data; 1454 /* Make zero terminated copy of the OBP_RAW file */
1455 cfg.raw = kmemdup_nul(fw->data, fw->size, GFP_KERNEL);
1456 if (!cfg.raw)
1457 return -ENOMEM;
1458
1455 cfg.raw_size = fw->size; 1459 cfg.raw_size = fw->size;
1456 1460
1457 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1); 1461 mxt_update_crc(data, MXT_COMMAND_REPORTALL, 1);
1458 1462
1459 if (strncmp(cfg.raw, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) { 1463 if (strncmp(cfg.raw, MXT_CFG_MAGIC, strlen(MXT_CFG_MAGIC))) {
1460 dev_err(dev, "Unrecognised config file\n"); 1464 dev_err(dev, "Unrecognised config file\n");
1461 return -EINVAL; 1465 ret = -EINVAL;
1466 goto release_raw;
1462 } 1467 }
1463 1468
1464 cfg.raw_pos = strlen(MXT_CFG_MAGIC); 1469 cfg.raw_pos = strlen(MXT_CFG_MAGIC);
@@ -1470,7 +1475,8 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
1470 &offset); 1475 &offset);
1471 if (ret != 1) { 1476 if (ret != 1) {
1472 dev_err(dev, "Bad format\n"); 1477 dev_err(dev, "Bad format\n");
1473 return -EINVAL; 1478 ret = -EINVAL;
1479 goto release_raw;
1474 } 1480 }
1475 1481
1476 cfg.raw_pos += offset; 1482 cfg.raw_pos += offset;
@@ -1478,26 +1484,30 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
1478 1484
1479 if (cfg.info.family_id != data->info->family_id) { 1485 if (cfg.info.family_id != data->info->family_id) {
1480 dev_err(dev, "Family ID mismatch!\n"); 1486 dev_err(dev, "Family ID mismatch!\n");
1481 return -EINVAL; 1487 ret = -EINVAL;
1488 goto release_raw;
1482 } 1489 }
1483 1490
1484 if (cfg.info.variant_id != data->info->variant_id) { 1491 if (cfg.info.variant_id != data->info->variant_id) {
1485 dev_err(dev, "Variant ID mismatch!\n"); 1492 dev_err(dev, "Variant ID mismatch!\n");
1486 return -EINVAL; 1493 ret = -EINVAL;
1494 goto release_raw;
1487 } 1495 }
1488 1496
1489 /* Read CRCs */ 1497 /* Read CRCs */
1490 ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &info_crc, &offset); 1498 ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &info_crc, &offset);
1491 if (ret != 1) { 1499 if (ret != 1) {
1492 dev_err(dev, "Bad format: failed to parse Info CRC\n"); 1500 dev_err(dev, "Bad format: failed to parse Info CRC\n");
1493 return -EINVAL; 1501 ret = -EINVAL;
1502 goto release_raw;
1494 } 1503 }
1495 cfg.raw_pos += offset; 1504 cfg.raw_pos += offset;
1496 1505
1497 ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &config_crc, &offset); 1506 ret = sscanf(cfg.raw + cfg.raw_pos, "%x%n", &config_crc, &offset);
1498 if (ret != 1) { 1507 if (ret != 1) {
1499 dev_err(dev, "Bad format: failed to parse Config CRC\n"); 1508 dev_err(dev, "Bad format: failed to parse Config CRC\n");
1500 return -EINVAL; 1509 ret = -EINVAL;
1510 goto release_raw;
1501 } 1511 }
1502 cfg.raw_pos += offset; 1512 cfg.raw_pos += offset;
1503 1513
@@ -1530,8 +1540,10 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
1530 MXT_INFO_CHECKSUM_SIZE; 1540 MXT_INFO_CHECKSUM_SIZE;
1531 cfg.mem_size = data->mem_size - cfg.start_ofs; 1541 cfg.mem_size = data->mem_size - cfg.start_ofs;
1532 cfg.mem = kzalloc(cfg.mem_size, GFP_KERNEL); 1542 cfg.mem = kzalloc(cfg.mem_size, GFP_KERNEL);
1533 if (!cfg.mem) 1543 if (!cfg.mem) {
1534 return -ENOMEM; 1544 ret = -ENOMEM;
1545 goto release_raw;
1546 }
1535 1547
1536 ret = mxt_prepare_cfg_mem(data, &cfg); 1548 ret = mxt_prepare_cfg_mem(data, &cfg);
1537 if (ret) 1549 if (ret)
@@ -1570,6 +1582,8 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *fw)
1570 /* T7 config may have changed */ 1582 /* T7 config may have changed */
1571 mxt_init_t7_power_cfg(data); 1583 mxt_init_t7_power_cfg(data);
1572 1584
1585release_raw:
1586 kfree(cfg.raw);
1573release_mem: 1587release_mem:
1574 kfree(cfg.mem); 1588 kfree(cfg.mem);
1575 return ret; 1589 return ret;