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.

+18 -1
+18 -1
drivers/misc/eeprom/at24.c
··· 425 425 memset(msg, 0, sizeof(msg)); 426 426 msg[0].addr = client->addr; 427 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 430 msg[0].len = 1; 430 431 msg[1].addr = client->addr; 431 432 msg[1].flags = I2C_M_RD; ··· 569 568 if (unlikely(!count)) 570 569 return count; 571 570 571 + if (off + count > at24->chip.byte_len) 572 + return -EINVAL; 573 + 572 574 client = at24_translate_offset(at24, &off); 573 575 574 576 ret = pm_runtime_get_sync(&client->dev); ··· 615 611 int ret; 616 612 617 613 if (unlikely(!count)) 614 + return -EINVAL; 615 + 616 + if (off + count > at24->chip.byte_len) 618 617 return -EINVAL; 619 618 620 619 client = at24_translate_offset(at24, &off); ··· 736 729 if (!is_power_of_2(chip.page_size)) 737 730 dev_warn(&client->dev, 738 731 "page_size looks suspicious (no power of 2)!\n"); 732 + 733 + /* 734 + * REVISIT: the size of the EUI-48 byte array is 6 in at24mac402, while 735 + * the call to ilog2() in AT24_DEVICE_MAGIC() rounds it down to 4. 736 + * 737 + * Eventually we'll get rid of the magic values altoghether in favor of 738 + * real structs, but for now just manually set the right size. 739 + */ 740 + if (chip.flags & AT24_FLAG_MAC && chip.byte_len == 4) 741 + chip.byte_len = 6; 739 742 740 743 /* Use I2C operations unless we're stuck with SMBus extensions. */ 741 744 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {