Users can call the gpio_ioctl() interface to get information about gpio chip lines. Lines on the chip are identified by an offset in the range of [0,chip.lines). Offset is copied from user and then used as an array index to get the gpio descriptor without sanitization. This change ensures that the offset is sanitized by using "array_index_nospec" to mitigate any possibility of speculative information leaks. This bug was discovered and resolved using Coverity Static Analysis Security Testing (SAST) by Synopsys, Inc. Fixes: aad955842d1c ("gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL") Signed-off-by: Hagar Hemdan <hagarhem@xxxxxxxxxx> --- Only compile tested, no access to HW. --- drivers/gpio/gpiolib-cdev.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 9dad67ea2597..215c03e6808f 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -20,6 +20,7 @@ #include <linux/kfifo.h> #include <linux/module.h> #include <linux/mutex.h> +#include <linux/nospec.h> #include <linux/overflow.h> #include <linux/pinctrl/consumer.h> #include <linux/poll.h> @@ -2170,7 +2171,8 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip) lflags = eventreq.handleflags; eflags = eventreq.eventflags; - desc = gpio_device_get_desc(gdev, offset); + desc = gpio_device_get_desc(gdev, + array_index_nospec(offset, gdev->ngpio)); if (IS_ERR(desc)) return PTR_ERR(desc); @@ -2477,7 +2479,8 @@ static int lineinfo_get_v1(struct gpio_chardev_data *cdev, void __user *ip, return -EFAULT; /* this doubles as a range check on line_offset */ - desc = gpio_device_get_desc(cdev->gdev, lineinfo.line_offset); + desc = gpio_device_get_desc(cdev->gdev, + array_index_nospec(lineinfo.line_offset, cdev->gdev->ngpio)); if (IS_ERR(desc)) return PTR_ERR(desc); @@ -2514,7 +2517,8 @@ static int lineinfo_get(struct gpio_chardev_data *cdev, void __user *ip, if (memchr_inv(lineinfo.padding, 0, sizeof(lineinfo.padding))) return -EINVAL; - desc = gpio_device_get_desc(cdev->gdev, lineinfo.offset); + desc = gpio_device_get_desc(cdev->gdev, + array_index_nospec(lineinfo.offset, cdev->gdev->ngpio)); if (IS_ERR(desc)) return PTR_ERR(desc); -- 2.40.1