Commit 31d04ca1 authored by Timur Tabi's avatar Timur Tabi Committed by Greg Kroah-Hartman

gpioib: do not free unrequested descriptors

commit ab3dbcf7 upstream.

If the main loop in linehandle_create() encounters an error, it
unwinds completely by freeing all previously requested GPIO
descriptors.  However, if the error occurs in the beginning of
the loop before that GPIO is requested, then the exit code
attempts to free a null descriptor.  If extrachecks is enabled,
gpiod_free() triggers a WARN_ON.

Instead, keep a separate count of legitimate GPIOs so that only
those are freed.

Cc: stable@vger.kernel.org
Fixes: d7c51b47 ("gpio: userspace ABI for reading/writing GPIO lines")
Reviewed-by: default avatarBjorn Andersson <bjorn.andersson@linaro.org>
Signed-off-by: default avatarTimur Tabi <timur@codeaurora.org>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b8c32088
...@@ -425,7 +425,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ...@@ -425,7 +425,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
struct gpiohandle_request handlereq; struct gpiohandle_request handlereq;
struct linehandle_state *lh; struct linehandle_state *lh;
struct file *file; struct file *file;
int fd, i, ret; int fd, i, count = 0, ret;
if (copy_from_user(&handlereq, ip, sizeof(handlereq))) if (copy_from_user(&handlereq, ip, sizeof(handlereq)))
return -EFAULT; return -EFAULT;
...@@ -471,6 +471,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ...@@ -471,6 +471,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
if (ret) if (ret)
goto out_free_descs; goto out_free_descs;
lh->descs[i] = desc; lh->descs[i] = desc;
count = i;
if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW) if (lflags & GPIOHANDLE_REQUEST_ACTIVE_LOW)
set_bit(FLAG_ACTIVE_LOW, &desc->flags); set_bit(FLAG_ACTIVE_LOW, &desc->flags);
...@@ -537,7 +538,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip) ...@@ -537,7 +538,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
out_put_unused_fd: out_put_unused_fd:
put_unused_fd(fd); put_unused_fd(fd);
out_free_descs: out_free_descs:
for (; i >= 0; i--) for (i = 0; i < count; i++)
gpiod_free(lh->descs[i]); gpiod_free(lh->descs[i]);
kfree(lh->label); kfree(lh->label);
out_free_lh: out_free_lh:
......
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