aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Fishman <AviFishman70@gmail.com>2017-10-05 11:25:16 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-10-05 11:25:16 +0200
commitb5d9ba8fe64a0aacf99fd1eec10375a98104a5ea (patch)
tree814c48b7c5a35fbb141fb8be939f17b3145d9307
parent6f97b30a904407c1f1701d937d9258ca9175c6ab (diff)
downloadbusybox-w32-b5d9ba8fe64a0aacf99fd1eec10375a98104a5ea.tar.gz
busybox-w32-b5d9ba8fe64a0aacf99fd1eec10375a98104a5ea.tar.bz2
busybox-w32-b5d9ba8fe64a0aacf99fd1eec10375a98104a5ea.zip
i2cset: fix 'i' & 's' modes (3 extra bytes were sent)
When 'i' or 's' modes are selected block array is filled from offset 3 (blen = 3) but copied to data.block buffer from offset 0 so first 3 bytes contains garbage from stack. The buffer that is sent is also 3 bytes too long due to those extra 3 bytes. Signed-off-by: Avi Fishman <AviFishman70@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--miscutils/i2c_tools.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/miscutils/i2c_tools.c b/miscutils/i2c_tools.c
index fc392d9dc..82f9842bd 100644
--- a/miscutils/i2c_tools.c
+++ b/miscutils/i2c_tools.c
@@ -562,14 +562,19 @@ int i2cset_main(int argc, char **argv)
562 opt_m = (1 << 2), opt_r = (1 << 3); 562 opt_m = (1 << 2), opt_r = (1 << 3);
563 563
564 int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0; 564 int bus_num, bus_addr, data_addr, mode = I2C_SMBUS_BYTE, pec = 0;
565 int val, blen = 0, mask = 0, fd, status; 565 int val, blen, mask, fd, status;
566 unsigned char block[I2C_SMBUS_BLOCK_MAX]; 566 unsigned char block[I2C_SMBUS_BLOCK_MAX];
567 char *opt_m_arg = NULL; 567 char *opt_m_arg = NULL;
568 unsigned opts; 568 unsigned opts;
569 569
570 opts = getopt32(argv, "^" "fym:r" "\0" "-3"/*from 3 to ? args*/, &opt_m_arg); 570 opts = getopt32(argv, "^"
571 "fym:r"
572 "\0" "-3", /* minimum 3 args */
573 &opt_m_arg
574 );
571 argv += optind; 575 argv += optind;
572 argc -= optind; 576 argc -= optind;
577 argc--; /* now argv[argc] is last arg */
573 578
574 bus_num = i2c_bus_lookup(argv[0]); 579 bus_num = i2c_bus_lookup(argv[0]);
575 bus_addr = i2c_parse_bus_addr(argv[1]); 580 bus_addr = i2c_parse_bus_addr(argv[1]);
@@ -579,20 +584,26 @@ int i2cset_main(int argc, char **argv)
579 if (!argv[4] && argv[3][0] != 'c') { 584 if (!argv[4] && argv[3][0] != 'c') {
580 mode = I2C_SMBUS_BYTE_DATA; /* Implicit b */ 585 mode = I2C_SMBUS_BYTE_DATA; /* Implicit b */
581 } else { 586 } else {
582 switch (argv[argc-1][0]) { 587 switch (argv[argc][0]) {
583 case 'c': /* Already set */ break; 588 case 'c': /* Already set */
584 case 'b': mode = I2C_SMBUS_BYTE_DATA; break; 589 break;
585 case 'w': mode = I2C_SMBUS_WORD_DATA; break; 590 case 'b': mode = I2C_SMBUS_BYTE_DATA;
586 case 's': mode = I2C_SMBUS_BLOCK_DATA; break; 591 break;
587 case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA; break; 592 case 'w': mode = I2C_SMBUS_WORD_DATA;
593 break;
594 case 's': mode = I2C_SMBUS_BLOCK_DATA;
595 break;
596 case 'i': mode = I2C_SMBUS_I2C_BLOCK_DATA;
597 break;
588 default: 598 default:
589 bb_error_msg("invalid mode"); 599 bb_error_msg("invalid mode");
590 bb_show_usage(); 600 bb_show_usage();
591 } 601 }
592 602
593 pec = argv[argc-1][1] == 'p'; 603 pec = (argv[argc][1] == 'p');
594 if (mode == I2C_SMBUS_BLOCK_DATA || 604 if (mode == I2C_SMBUS_BLOCK_DATA
595 mode == I2C_SMBUS_I2C_BLOCK_DATA) { 605 || mode == I2C_SMBUS_I2C_BLOCK_DATA
606 ) {
596 if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA) 607 if (pec && mode == I2C_SMBUS_I2C_BLOCK_DATA)
597 bb_error_msg_and_die( 608 bb_error_msg_and_die(
598 "PEC not supported for I2C " 609 "PEC not supported for I2C "
@@ -606,6 +617,8 @@ int i2cset_main(int argc, char **argv)
606 } 617 }
607 618
608 /* Prepare the value(s) to be written according to current mode. */ 619 /* Prepare the value(s) to be written according to current mode. */
620 mask = 0;
621 blen = 0;
609 switch (mode) { 622 switch (mode) {
610 case I2C_SMBUS_BYTE_DATA: 623 case I2C_SMBUS_BYTE_DATA:
611 val = xstrtou_range(argv[3], 0, 0, 0xff); 624 val = xstrtou_range(argv[3], 0, 0, 0xff);
@@ -615,8 +628,9 @@ int i2cset_main(int argc, char **argv)
615 break; 628 break;
616 case I2C_SMBUS_BLOCK_DATA: 629 case I2C_SMBUS_BLOCK_DATA:
617 case I2C_SMBUS_I2C_BLOCK_DATA: 630 case I2C_SMBUS_I2C_BLOCK_DATA:
618 for (blen = 3; blen < (argc - 1); blen++) 631 for (blen = 3; blen < argc; blen++)
619 block[blen] = xstrtou_range(argv[blen], 0, 0, 0xff); 632 block[blen - 3] = xstrtou_range(argv[blen], 0, 0, 0xff);
633 blen -= 3;
620 val = -1; 634 val = -1;
621 break; 635 break;
622 default: 636 default: