Skip to content

Commit fc92d9e

Browse files
Wei Yongjunjic23
authored andcommitted
iio: health: afe4404: Fix oob read in afe4404_[read|write]_raw
KASAN report out-of-bounds read as follows: BUG: KASAN: global-out-of-bounds in afe4404_read_raw+0x2ce/0x380 Read of size 4 at addr ffffffffc00e4658 by task cat/278 Call Trace: afe4404_read_raw iio_read_channel_info dev_attr_show The buggy address belongs to the variable: afe4404_channel_leds+0x18/0xffffffffffffe9c0 This issue can be reproduce by singe command: $ cat /sys/bus/i2c/devices/0-0058/iio\:device0/in_intensity6_raw The array size of afe4404_channel_leds and afe4404_channel_offdacs are less than channels, so access with chan->address cause OOB read in afe4404_[read|write]_raw. Fix it by moving access before use them. Fixes: b36e825 ("iio: health/afe440x: Use regmap fields") Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com> Acked-by: Andrew Davis <afd@ti.com> Link: https://lore.kernel.org/r/20221107152010.95937-1-weiyongjun@huaweicloud.com Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
1 parent 58143c1 commit fc92d9e

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

drivers/iio/health/afe4404.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,20 +250,20 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
250250
int *val, int *val2, long mask)
251251
{
252252
struct afe4404_data *afe = iio_priv(indio_dev);
253-
unsigned int value_reg = afe4404_channel_values[chan->address];
254-
unsigned int led_field = afe4404_channel_leds[chan->address];
255-
unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
253+
unsigned int value_reg, led_field, offdac_field;
256254
int ret;
257255

258256
switch (chan->type) {
259257
case IIO_INTENSITY:
260258
switch (mask) {
261259
case IIO_CHAN_INFO_RAW:
260+
value_reg = afe4404_channel_values[chan->address];
262261
ret = regmap_read(afe->regmap, value_reg, val);
263262
if (ret)
264263
return ret;
265264
return IIO_VAL_INT;
266265
case IIO_CHAN_INFO_OFFSET:
266+
offdac_field = afe4404_channel_offdacs[chan->address];
267267
ret = regmap_field_read(afe->fields[offdac_field], val);
268268
if (ret)
269269
return ret;
@@ -273,6 +273,7 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
273273
case IIO_CURRENT:
274274
switch (mask) {
275275
case IIO_CHAN_INFO_RAW:
276+
led_field = afe4404_channel_leds[chan->address];
276277
ret = regmap_field_read(afe->fields[led_field], val);
277278
if (ret)
278279
return ret;
@@ -295,19 +296,20 @@ static int afe4404_write_raw(struct iio_dev *indio_dev,
295296
int val, int val2, long mask)
296297
{
297298
struct afe4404_data *afe = iio_priv(indio_dev);
298-
unsigned int led_field = afe4404_channel_leds[chan->address];
299-
unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
299+
unsigned int led_field, offdac_field;
300300

301301
switch (chan->type) {
302302
case IIO_INTENSITY:
303303
switch (mask) {
304304
case IIO_CHAN_INFO_OFFSET:
305+
offdac_field = afe4404_channel_offdacs[chan->address];
305306
return regmap_field_write(afe->fields[offdac_field], val);
306307
}
307308
break;
308309
case IIO_CURRENT:
309310
switch (mask) {
310311
case IIO_CHAN_INFO_RAW:
312+
led_field = afe4404_channel_leds[chan->address];
311313
return regmap_field_write(afe->fields[led_field], val);
312314
}
313315
break;

0 commit comments

Comments
 (0)