Skip to contentSkip to conversation

iio:core: Fix bug in length of event info_mask and catch unhandled bits set in masks.

PATCH In review Jonathan Cameron 1 participant 2 messages Mar 1, 2014 – Mar 15, 2014 IIO

lore
Share & tools
lore

Jonathan Cameron

author maintainer
#0 lore raw

PATCH 1/1 iio:core: Fix bug in length of event info_mask and catch unhandled bits set in masks.

The unhandled bits case was highlighted by smatch:
CHECK drivers/iio/industrialio-core.c
drivers/iio/industrialio-core.c:719 iio_device_add_info_mask_type() error: buffer overflow 'iio_chan_info_postfix' 17 <= 31
CC [M] drivers/iio/industrialio-core.o
CHECK drivers/iio/industrialio-event.c
drivers/iio/industrialio-event.c:327 iio_device_add_event() error: buffer overflow 'iio_ev_info_text' 3 <= 3

The incorrect limit for the for_each_set_bit loop was noticed whilst fixing this other case. Note that as we only have 3 possible entries a the moment and the value was set to 4, the bug would not have any effect currently. It will bite fairly soon though, so best fix it now.

Cc Lars-Peter Clausen <[email protected]>
Cc Dan Carpenter <[email protected]>
---
 drivers/iio/industrialio-core.c  | 2 ++
 drivers/iio/industrialio-event.c | 4 +++-
 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/iio/industrialio-core.c +2 -0
index ede16aec..e4961b1 100644
@@ -716,6 +716,8 @@ static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
 	int i, ret, attrcount = 0;
 
 	for_each_set_bit(i, infomask, sizeof(infomask)*8) {
+		if (i >= ARRAY_SIZE(iio_chan_info_postfix))
+			return -EINVAL;
 		ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
 					     chan,
 					     &iio_read_channel_info,
drivers/iio/industrialio-event.c +3 -1
index ea6e06b..dddfb0f 100644
@@ -321,7 +321,9 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
 	char *postfix;
 	int ret;
 
-	for_each_set_bit(i, mask, sizeof(*mask)) {
+	for_each_set_bit(i, mask, sizeof(*mask)*8) {
+		if (i >= ARRAY_SIZE(iio_ev_info_text))
+			return -EINVAL;
 		postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
 				iio_ev_type_text[type], iio_ev_dir_text[dir],
 				iio_ev_info_text[i]);
Signature · 1 line
1.9.0
author maintainer
#1 lore raw
Quoted 7 lines · Jonathan Cameron

The unhandled bits case was highlighted by smatch:
CHECK drivers/iio/industrialio-core.c
drivers/iio/industrialio-core.c:719 iio_device_add_info_mask_type() error: buffer overflow 'iio_chan_info_postfix' 17 <= 31
CC [M] drivers/iio/industrialio-core.o
CHECK drivers/iio/industrialio-event.c
drivers/iio/industrialio-event.c:327 iio_device_add_event() error: buffer overflow 'iio_ev_info_text' 3 <= 3

Quoted 8 lines

The incorrect limit for the for_each_set_bit loop was noticed whilst fixing this other case. Note that as we only have 3 possible entries a the moment and the value was set to 4, the bug would not have any effect currently. It will bite fairly soon though, so best fix it now.

Cc Lars-Peter Clausen <[email protected]>
Cc Dan Carpenter <[email protected]>

Executive descision time :) Applied to the togreg branch of iio.git as clearly no one cares.

Quoted 34 lines
---
  drivers/iio/industrialio-core.c  | 2 ++
  drivers/iio/industrialio-event.c | 4 +++-
  2 files changed, 5 insertions(+), 1 deletion(-)
drivers/iio/industrialio-core.c +2 -0
index ede16aec..e4961b1 100644
@@ -716,6 +716,8 @@ static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
  	int i, ret, attrcount = 0;
 
  	for_each_set_bit(i, infomask, sizeof(infomask)*8) {
+		if (i >= ARRAY_SIZE(iio_chan_info_postfix))
+			return -EINVAL;
  		ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
  					     chan,
  					     &iio_read_channel_info,
drivers/iio/industrialio-event.c +3 -1
index ea6e06b..dddfb0f 100644
@@ -321,7 +321,9 @@ static int iio_device_add_event(struct iio_dev *indio_dev,
  	char *postfix;
  	int ret;
 
-	for_each_set_bit(i, mask, sizeof(*mask)) {
+	for_each_set_bit(i, mask, sizeof(*mask)*8) {
+		if (i >= ARRAY_SIZE(iio_ev_info_text))
+			return -EINVAL;
  		postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
  				iio_ev_type_text[type], iio_ev_dir_text[dir],
  				iio_ev_info_text[i]);