aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWolfram Sang <wsa@the-dreams.de>2017-12-02 17:32:13 -0500
committerWolfram Sang <wsa@the-dreams.de>2017-12-03 09:55:20 -0500
commitedef30980dc06bea547baefcfc8d910682b6e060 (patch)
tree2edc620174584101b8cda42f078bce9d0103204e
parent66a7c84d677e8e4a5a2ef4afdb9bd52e1399a866 (diff)
parentd9bcd462daf34aebb8de9ad7f76de0198bb5a0f0 (diff)
Merge tag 'at24-4.15-fixes-for-wolfram' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into i2c/for-current
Please consider pulling the following fixes for v4.15. While it doesn't fix any regression introduced in the v4.15 merge window, we have a feature in at24 since linux v4.8 - reading the mac address block from at24mac series - which turned out to be not working. This pull request contains changes that fix it together with a patch that hardens the read and write argument sanitization with out-of-bounds checks that were missing.
-rw-r--r--drivers/misc/eeprom/at24.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index e0b4b36ef010..305a7a464d09 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -425,7 +425,8 @@ static ssize_t at24_eeprom_read_mac(struct at24_data *at24, char *buf,
425 memset(msg, 0, sizeof(msg)); 425 memset(msg, 0, sizeof(msg));
426 msg[0].addr = client->addr; 426 msg[0].addr = client->addr;
427 msg[0].buf = addrbuf; 427 msg[0].buf = addrbuf;
428 addrbuf[0] = 0x90 + offset; 428 /* EUI-48 starts from 0x9a, EUI-64 from 0x98 */
429 addrbuf[0] = 0xa0 - at24->chip.byte_len + offset;
429 msg[0].len = 1; 430 msg[0].len = 1;
430 msg[1].addr = client->addr; 431 msg[1].addr = client->addr;
431 msg[1].flags = I2C_M_RD; 432 msg[1].flags = I2C_M_RD;
@@ -568,6 +569,9 @@ static int at24_read(void *priv, unsigned int off, void *val, size_t count)
568 if (unlikely(!count)) 569 if (unlikely(!count))
569 return count; 570 return count;
570 571
572 if (off + count > at24->chip.byte_len)
573 return -EINVAL;
574
571 client = at24_translate_offset(at24, &off); 575 client = at24_translate_offset(at24, &off);
572 576
573 ret = pm_runtime_get_sync(&client->dev); 577 ret = pm_runtime_get_sync(&client->dev);
@@ -613,6 +617,9 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
613 if (unlikely(!count)) 617 if (unlikely(!count))
614 return -EINVAL; 618 return -EINVAL;
615 619
620 if (off + count > at24->chip.byte_len)
621 return -EINVAL;
622
616 client = at24_translate_offset(at24, &off); 623 client = at24_translate_offset(at24, &off);
617 624
618 ret = pm_runtime_get_sync(&client->dev); 625 ret = pm_runtime_get_sync(&client->dev);
@@ -730,6 +737,16 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
730 dev_warn(&client->dev, 737 dev_warn(&client->dev,
731 "page_size looks suspicious (no power of 2)!\n"); 738 "page_size looks suspicious (no power of 2)!\n");
732 739
740 /*
741 * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while
742 * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4.
743 *
744 * Eventually we'll get rid of the magic values altoghether in favor of
745 * real structs, but for now just manually set the right size.
746 */
747 if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4)
748 chip.byte_len = 6;
749
733 /* Use I2C operations unless we're stuck with SMBus extensions. */ 750 /* Use I2C operations unless we're stuck with SMBus extensions. */
734 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 751 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
735 if (chip.flags & AT24_FLAG_ADDR16) 752 if (chip.flags & AT24_FLAG_ADDR16)