Patch "iio: health: afe4404: Fix oob read in afe4404_[read|write]_raw" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    iio: health: afe4404: Fix oob read in afe4404_[read|write]_raw

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     iio-health-afe4404-fix-oob-read-in-afe4404_-read-wri.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 04fa1f84a0125754a45fa13b9e409346f61ca0dc
Author: Wei Yongjun <weiyongjun1@xxxxxxxxxx>
Date:   Mon Nov 7 15:20:10 2022 +0000

    iio: health: afe4404: Fix oob read in afe4404_[read|write]_raw
    
    [ Upstream commit fc92d9e3de0b2d30a3ccc08048a5fad533e4672b ]
    
    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: b36e8257641a ("iio: health/afe440x: Use regmap fields")
    Signed-off-by: Wei Yongjun <weiyongjun1@xxxxxxxxxx>
    Acked-by: Andrew Davis <afd@xxxxxx>
    Link: https://lore.kernel.org/r/20221107152010.95937-1-weiyongjun@xxxxxxxxxxxxxxx
    Signed-off-by: Jonathan Cameron <Jonathan.Cameron@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/iio/health/afe4404.c b/drivers/iio/health/afe4404.c
index cebb1fd4d0b1..7780e9b312b3 100644
--- a/drivers/iio/health/afe4404.c
+++ b/drivers/iio/health/afe4404.c
@@ -250,20 +250,20 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
 			    int *val, int *val2, long mask)
 {
 	struct afe4404_data *afe = iio_priv(indio_dev);
-	unsigned int value_reg = afe4404_channel_values[chan->address];
-	unsigned int led_field = afe4404_channel_leds[chan->address];
-	unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
+	unsigned int value_reg, led_field, offdac_field;
 	int ret;
 
 	switch (chan->type) {
 	case IIO_INTENSITY:
 		switch (mask) {
 		case IIO_CHAN_INFO_RAW:
+			value_reg = afe4404_channel_values[chan->address];
 			ret = regmap_read(afe->regmap, value_reg, val);
 			if (ret)
 				return ret;
 			return IIO_VAL_INT;
 		case IIO_CHAN_INFO_OFFSET:
+			offdac_field = afe4404_channel_offdacs[chan->address];
 			ret = regmap_field_read(afe->fields[offdac_field], val);
 			if (ret)
 				return ret;
@@ -273,6 +273,7 @@ static int afe4404_read_raw(struct iio_dev *indio_dev,
 	case IIO_CURRENT:
 		switch (mask) {
 		case IIO_CHAN_INFO_RAW:
+			led_field = afe4404_channel_leds[chan->address];
 			ret = regmap_field_read(afe->fields[led_field], val);
 			if (ret)
 				return ret;
@@ -295,19 +296,20 @@ static int afe4404_write_raw(struct iio_dev *indio_dev,
 			     int val, int val2, long mask)
 {
 	struct afe4404_data *afe = iio_priv(indio_dev);
-	unsigned int led_field = afe4404_channel_leds[chan->address];
-	unsigned int offdac_field = afe4404_channel_offdacs[chan->address];
+	unsigned int led_field, offdac_field;
 
 	switch (chan->type) {
 	case IIO_INTENSITY:
 		switch (mask) {
 		case IIO_CHAN_INFO_OFFSET:
+			offdac_field = afe4404_channel_offdacs[chan->address];
 			return regmap_field_write(afe->fields[offdac_field], val);
 		}
 		break;
 	case IIO_CURRENT:
 		switch (mask) {
 		case IIO_CHAN_INFO_RAW:
+			led_field = afe4404_channel_leds[chan->address];
 			return regmap_field_write(afe->fields[led_field], val);
 		}
 		break;



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux