Commit 1d656bd2 authored by Kent Gibson's avatar Kent Gibson Committed by Bartosz Golaszewski

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
(bdbbae24), so add protection for that.

Fixes: bdbbae24 ("gpiolib: protect the GPIO device against being dropped while in use by user-space")
Fixes: d7c51b47 ("gpio: userspace ABI for reading/writing GPIO lines")
Fixes: 3c0d9c63 ("gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL")
Fixes: aad95584 ("gpiolib: cdev: support GPIO_V2_GET_LINEINFO_IOCTL and GPIO_V2_GET_LINEINFO_WATCH_IOCTL")
Signed-off-by: default avatarKent Gibson <warthog618@gmail.com>
Signed-off-by: default avatarBartosz Golaszewski <bartosz.golaszewski@linaro.org>
parent ceb6a6f0
...@@ -2481,10 +2481,7 @@ static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip) ...@@ -2481,10 +2481,7 @@ static int lineinfo_unwatch(struct gpio_chardev_data *cdev, void __user *ip)
return 0; return 0;
} }
/* static long gpio_ioctl_unlocked(struct file *file, unsigned int cmd, unsigned long arg)
* gpio_ioctl() - ioctl handler for the GPIO chardev
*/
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ {
struct gpio_chardev_data *cdev = file->private_data; struct gpio_chardev_data *cdev = file->private_data;
struct gpio_device *gdev = cdev->gdev; struct gpio_device *gdev = cdev->gdev;
...@@ -2521,6 +2518,17 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -2521,6 +2518,17 @@ static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
} }
} }
/*
* gpio_ioctl() - ioctl handler for the GPIO chardev
*/
static long gpio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
struct gpio_chardev_data *cdev = file->private_data;
return call_ioctl_locked(file, cmd, arg, cdev->gdev,
gpio_ioctl_unlocked);
}
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
static long gpio_ioctl_compat(struct file *file, unsigned int cmd, static long gpio_ioctl_compat(struct file *file, unsigned int cmd,
unsigned long arg) unsigned long arg)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment