Skip to content

Commit

Permalink
gpiolib: Never return internal error codes to user space
Browse files Browse the repository at this point in the history
[ Upstream commit 95a4eed ]

Currently it's possible that character device interface may return
the error codes which are not supposed to be seen by user space.
In this case it's EPROBE_DEFER.

Wrap it to return -ENODEV instead as sysfs does.

Fixes: d7c51b4 ("gpio: userspace ABI for reading/writing GPIO lines")
Fixes: 61f922d ("gpio: userspace ABI for reading GPIO line events")
Fixes: 3c0d9c6 ("gpiolib: cdev: support GPIO_V2_GET_LINE_IOCTL and GPIO_V2_LINE_GET_VALUES_IOCTL")
Reported-by: Suresh Balakrishnan <suresh.balakrishnan@intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
andy-shev authored and gregkh committed Feb 16, 2022
1 parent 4287509 commit a01aba1
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
6 changes: 3 additions & 3 deletions drivers/gpio/gpiolib-cdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
goto out_free_lh;
}

ret = gpiod_request(desc, lh->label);
ret = gpiod_request_user(desc, lh->label);
if (ret)
goto out_free_lh;
lh->descs[i] = desc;
Expand Down Expand Up @@ -1378,7 +1378,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip)
goto out_free_linereq;
}

ret = gpiod_request(desc, lr->label);
ret = gpiod_request_user(desc, lr->label);
if (ret)
goto out_free_linereq;

Expand Down Expand Up @@ -1764,7 +1764,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
}
}

ret = gpiod_request(desc, le->label);
ret = gpiod_request_user(desc, le->label);
if (ret)
goto out_free_le;
le->desc = desc;
Expand Down
7 changes: 2 additions & 5 deletions drivers/gpio/gpiolib-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -475,12 +475,9 @@ static ssize_t export_store(struct class *class,
* they may be undone on its behalf too.
*/

status = gpiod_request(desc, "sysfs");
if (status) {
if (status == -EPROBE_DEFER)
status = -ENODEV;
status = gpiod_request_user(desc, "sysfs");
if (status)
goto done;
}

status = gpiod_set_transitory(desc, false);
if (!status) {
Expand Down
12 changes: 12 additions & 0 deletions drivers/gpio/gpiolib.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ struct gpio_desc {

int gpiod_request(struct gpio_desc *desc, const char *label);
void gpiod_free(struct gpio_desc *desc);

static inline int gpiod_request_user(struct gpio_desc *desc, const char *label)
{
int ret;

ret = gpiod_request(desc, label);
if (ret == -EPROBE_DEFER)
ret = -ENODEV;

return ret;
}

int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
unsigned long lflags, enum gpiod_flags dflags);
int gpio_set_debounce_timeout(struct gpio_desc *desc, unsigned int debounce);
Expand Down

0 comments on commit a01aba1

Please sign in to comment.