From: Kent Gibson <[email protected]>

commit e95fbc130a162ba9ad956311b95aa0da269eea48 upstream.

linehandle_create should not allow both GPIOHANDLE_REQUEST_INPUT
and GPIOHANDLE_REQUEST_OUTPUT to be set.

Fixes: d7c51b47ac11 ("gpio: userspace ABI for reading/writing GPIO lines")
Cc: stable <[email protected]>
Signed-off-by: Kent Gibson <[email protected]>
Signed-off-by: Bartosz Golaszewski <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
 drivers/gpio/gpiolib.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -444,12 +444,23 @@ static int linehandle_create(struct gpio
        struct linehandle_state *lh;
        struct file *file;
        int fd, i, count = 0, ret;
+       u32 lflags;
 
        if (copy_from_user(&handlereq, ip, sizeof(handlereq)))
                return -EFAULT;
        if ((handlereq.lines == 0) || (handlereq.lines > GPIOHANDLES_MAX))
                return -EINVAL;
 
+       lflags = handlereq.flags;
+
+       /*
+        * Do not allow both INPUT & OUTPUT flags to be set as they are
+        * contradictory.
+        */
+       if ((lflags & GPIOHANDLE_REQUEST_INPUT) &&
+           (lflags & GPIOHANDLE_REQUEST_OUTPUT))
+               return -EINVAL;
+
        lh = kzalloc(sizeof(*lh), GFP_KERNEL);
        if (!lh)
                return -ENOMEM;
@@ -470,7 +481,6 @@ static int linehandle_create(struct gpio
        /* Request each GPIO */
        for (i = 0; i < handlereq.lines; i++) {
                u32 offset = handlereq.lineoffsets[i];
-               u32 lflags = handlereq.flags;
                struct gpio_desc *desc;
 
                if (offset >= gdev->ngpio) {


Reply via email to