Skip to content

Commit 1d656bd

Browse files
warthog618Bartosz Golaszewski
authored andcommitted
gpiolib: cdev: add gpio_device locking wrapper around gpio_ioctl()
While the GPIO cdev gpio_ioctl() call is in progress, the kernel can call gpiochip_remove() which will set gdev->chip to NULL, after which any subsequent access will cause a crash. gpio_ioctl() was overlooked by the previous fix to protect syscalls (bdbbae2), so add protection for that. Fixes: bdbbae2 ("gpiolib: protect the GPIO device against being dropped while in use by user-space") Fixes: d7c51b4 ("gpio: userspace ABI for reading/writing GPIO lines") Fixes: 3c0d9c6 ("gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL") Fixes: aad9558 ("gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL") Signed-off-by: Kent Gibson <warthog618@gmail.com> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
1 parent ceb6a6f commit 1d656bd

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

drivers/gpio/gpiolib-cdev.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,10 +2481,7 @@ static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip)
24812481
return 0;
24822482
}
24832483

2484-
/*
2485-
* gpio_ioctl() - ioctl handler for the GPIO chardev
2486-
*/
2487-
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2484+
static long gpio_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg)
24882485
{
24892486
struct gpio_chardev_data *cdev = file->private_data;
24902487
struct gpio_device *gdev = cdev->gdev;
@@ -2521,6 +2518,17 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
25212518
}
25222519
}
25232520

2521+
/*
2522+
* gpio_ioctl() - ioctl handler for the GPIO chardev
2523+
*/
2524+
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2525+
{
2526+
struct gpio_chardev_data *cdev = file->private_data;
2527+
2528+
return call_ioctl_locked(file, cmd, arg, cdev->gdev,
2529+
gpio_ioctl_unlocked);
2530+
}
2531+
25242532
#ifdef CONFIG_COMPAT
25252533
static long gpio_ioctl_compat(struct file *file, unsigned int cmd,
25262534
unsigned long arg)

0 commit comments

Comments
 (0)