]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
gpio: chardev: Return error for seek operations
authorLars-Peter Clausen <lars@metafoo.de>
Wed, 30 Nov 2016 12:05:21 +0000 (13:05 +0100)
committerLinus Walleij <linus.walleij@linaro.org>
Wed, 7 Dec 2016 14:23:39 +0000 (15:23 +0100)
The GPIO chardev is used for management tasks (allocating line and event
handles) and does neither support read() nor write() operations. Hence it
does not make much sense to allow seek operations.

Currently the chardev uses noop_llseek() for its seek implementation. This
function does not move the pointer and simply returns the current position
(always 0 for the GPIO chardev). noop_llseek() is primarily meant for
devices that can not support seek, but where there might be a user that
depends on the seek() operation succeeding. For newly added devices that
can not support seek operations it is recommended to use no_llseek(), which
will return an error. For more information see commit 6038f373a3dc
("llseek: automatically add .llseek fop").

Unfortunately this was overlooked when the GPIO chardev ABI was introduced.
But it is highly unlikely that since then userspace applications have
appeared that rely on being able to perform non-failing seek operations on
a GPIO chardev file descriptor. So it should be safe to change from
noop_llseel() to no_seek(). Also use nonseekable_open() in the chardev
open() callback to clear the FMODE_SEEK, FMODE_PREAD and FMODE_PWRITE flags
from the file. Neither of these should be set on a file that does not
support seek operations.

Cc: stable@vger.kernel.org
Fixes: 3c702e9987e2 ("gpio: add a userspace chardev ABI for GPIOs")
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
drivers/gpio/gpiolib.c

index e97e88e48191e512d1d3a689f7e5b3f249d06e48..0e29cb7456484ed755008127519fedf9eb0d6e6d 100644 (file)
@@ -913,7 +913,8 @@ static int gpio_chrdev_open(struct inode *inode, struct file *filp)
                return -ENODEV;
        get_device(&gdev->dev);
        filp->private_data = gdev;
-       return 0;
+
+       return nonseekable_open(inode, filp);
 }
 
 /**
@@ -938,7 +939,7 @@ static const struct file_operations gpio_fileops = {
        .release = gpio_chrdev_release,
        .open = gpio_chrdev_open,
        .owner = THIS_MODULE,
-       .llseek = noop_llseek,
+       .llseek = no_llseek,
        .unlocked_ioctl = gpio_ioctl,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = gpio_ioctl_compat,