mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 00:04:15 +08:00
iio: health: afe4404
: Fix oob read in afe4404_[read|write]_raw
[ Upstream commitfc92d9e3de
] 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:b36e825764
("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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
b1756af172
commit
5eb114f55b
@ -250,20 +250,20 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
|
|||||||
int *val, int *val2, long mask)
|
int *val, int *val2, long mask)
|
||||||
{
|
{
|
||||||
struct afe4404_data *afe = iio_priv(indio_dev);
|
struct afe4404_data *afe = iio_priv(indio_dev);
|
||||||
unsigned int value_reg = afe4404_channel_values[chan->address];
|
unsigned int value_reg, led_field, offdac_field;
|
||||||
unsigned int led_field = afe4404_channel_leds[chan->address];
|
|
||||||
unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (chan->type) {
|
switch (chan->type) {
|
||||||
case IIO_INTENSITY:
|
case IIO_INTENSITY:
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case IIO_CHAN_INFO_RAW:
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
value_reg = afe4404_channel_values[chan->address];
|
||||||
ret = regmap_read(afe->regmap, value_reg, val);
|
ret = regmap_read(afe->regmap, value_reg, val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
return IIO_VAL_INT;
|
return IIO_VAL_INT;
|
||||||
case IIO_CHAN_INFO_OFFSET:
|
case IIO_CHAN_INFO_OFFSET:
|
||||||
|
offdac_field = afe4404_channel_offdacs[chan->address];
|
||||||
ret = regmap_field_read(afe->fields[offdac_field], val);
|
ret = regmap_field_read(afe->fields[offdac_field], val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -273,6 +273,7 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
|
|||||||
case IIO_CURRENT:
|
case IIO_CURRENT:
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case IIO_CHAN_INFO_RAW:
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
led_field = afe4404_channel_leds[chan->address];
|
||||||
ret = regmap_field_read(afe->fields[led_field], val);
|
ret = regmap_field_read(afe->fields[led_field], val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -295,19 +296,20 @@ static int afe4404_write_raw(struct iio_dev *indio_dev,
|
|||||||
int val, int val2, long mask)
|
int val, int val2, long mask)
|
||||||
{
|
{
|
||||||
struct afe4404_data *afe = iio_priv(indio_dev);
|
struct afe4404_data *afe = iio_priv(indio_dev);
|
||||||
unsigned int led_field = afe4404_channel_leds[chan->address];
|
unsigned int led_field, offdac_field;
|
||||||
unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
|
|
||||||
|
|
||||||
switch (chan->type) {
|
switch (chan->type) {
|
||||||
case IIO_INTENSITY:
|
case IIO_INTENSITY:
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case IIO_CHAN_INFO_OFFSET:
|
case IIO_CHAN_INFO_OFFSET:
|
||||||
|
offdac_field = afe4404_channel_offdacs[chan->address];
|
||||||
return regmap_field_write(afe->fields[offdac_field], val);
|
return regmap_field_write(afe->fields[offdac_field], val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IIO_CURRENT:
|
case IIO_CURRENT:
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case IIO_CHAN_INFO_RAW:
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
led_field = afe4404_channel_leds[chan->address];
|
||||||
return regmap_field_write(afe->fields[led_field], val);
|
return regmap_field_write(afe->fields[led_field], val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user