aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuenter Roeck <linux@roeck-us.net>2017-07-11 23:53:55 -0400
committerGuenter Roeck <linux@roeck-us.net>2017-07-15 19:38:56 -0400
commit1009ccdc64ee2c8451f76b548589f6b989d13412 (patch)
tree1550e7c64fa36ed378ae26a874d9a694027d4d5a
parent5771a8c08880cdca3bfb4a3fc6d309d6bba20877 (diff)
hwmon: (applesmc) Avoid buffer overruns
gcc 7.1 complains that the driver uses sprintf() and thus does not validate the length of output buffers. drivers/hwmon/applesmc.c: In function 'applesmc_show_fan_position': drivers/hwmon/applesmc.c:82:21: warning: '%d' directive writing between 1 and 5 bytes into a region of size 4 Fix the problem by using scnprintf() instead of sprintf() throughout the driver. Also explicitly limit the number of supported fans to avoid actual buffer overruns and thus invalid keys. Signed-off-by: Guenter Roeck <linux@roeck-us.net>
-rw-r--r--drivers/hwmon/applesmc.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 0af7fd311979..76c34f4fde13 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -566,6 +566,8 @@ static int applesmc_init_smcreg_try(void)
566 if (ret) 566 if (ret)
567 return ret; 567 return ret;
568 s->fan_count = tmp[0]; 568 s->fan_count = tmp[0];
569 if (s->fan_count > 10)
570 s->fan_count = 10;
569 571
570 ret = applesmc_get_lower_bound(&s->temp_begin, "T"); 572 ret = applesmc_get_lower_bound(&s->temp_begin, "T");
571 if (ret) 573 if (ret)
@@ -811,7 +813,8 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
811 char newkey[5]; 813 char newkey[5];
812 u8 buffer[2]; 814 u8 buffer[2];
813 815
814 sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); 816 scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)],
817 to_index(attr));
815 818
816 ret = applesmc_read_key(newkey, buffer, 2); 819 ret = applesmc_read_key(newkey, buffer, 2);
817 speed = ((buffer[0] << 8 | buffer[1]) >> 2); 820 speed = ((buffer[0] << 8 | buffer[1]) >> 2);
@@ -834,7 +837,8 @@ static ssize_t applesmc_store_fan_speed(struct device *dev,
834 if (kstrtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000) 837 if (kstrtoul(sysfsbuf, 10, &speed) < 0 || speed >= 0x4000)
835 return -EINVAL; /* Bigger than a 14-bit value */ 838 return -EINVAL; /* Bigger than a 14-bit value */
836 839
837 sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); 840 scnprintf(newkey, sizeof(newkey), fan_speed_fmt[to_option(attr)],
841 to_index(attr));
838 842
839 buffer[0] = (speed >> 6) & 0xff; 843 buffer[0] = (speed >> 6) & 0xff;
840 buffer[1] = (speed << 2) & 0xff; 844 buffer[1] = (speed << 2) & 0xff;
@@ -903,7 +907,7 @@ static ssize_t applesmc_show_fan_position(struct device *dev,
903 char newkey[5]; 907 char newkey[5];
904 u8 buffer[17]; 908 u8 buffer[17];
905 909
906 sprintf(newkey, FAN_ID_FMT, to_index(attr)); 910 scnprintf(newkey, sizeof(newkey), FAN_ID_FMT, to_index(attr));
907 911
908 ret = applesmc_read_key(newkey, buffer, 16); 912 ret = applesmc_read_key(newkey, buffer, 16);
909 buffer[16] = 0; 913 buffer[16] = 0;
@@ -1116,7 +1120,8 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
1116 } 1120 }
1117 for (i = 0; i < num; i++) { 1121 for (i = 0; i < num; i++) {
1118 node = &grp->nodes[i]; 1122 node = &grp->nodes[i];
1119 sprintf(node->name, grp->format, i + 1); 1123 scnprintf(node->name, sizeof(node->name), grp->format,
1124 i + 1);
1120 node->sda.index = (grp->option << 16) | (i & 0xffff); 1125 node->sda.index = (grp->option << 16) | (i & 0xffff);
1121 node->sda.dev_attr.show = grp->show; 1126 node->sda.dev_attr.show = grp->show;
1122 node->sda.dev_attr.store = grp->store; 1127 node->sda.dev_attr.store = grp->store;