Re: [PATCH 4/8] gpiolib: sanitize the return value of gpio_chip::get()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Feb 10, 2025 at 11:51:58AM +0100, Bartosz Golaszewski wrote:
> From: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx>
> 
> As per the API contract, the get() callback is only allowed to return 0,
> 1 or a negative error number. Add a wrapper around the callback calls
> that filters out anything else.

...

> +static int gpiochip_get(struct gpio_chip *gc, unsigned int offset)
> +{
> +	int ret;
> +
> +	lockdep_assert_held(&gc->gpiodev->srcu);
> +
> +	if (!gc->get)
> +		return -EIO;
> +
> +	ret = gc->get(gc, offset);
> +	if (ret > 1)

Perhaps use the respective GPIO macro instead? Otherwise it's not clear what
the meaning of 1 is.

> +		ret = -EBADE;
> +
> +	return ret;
> +}
> +
>  static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *desc)
>  {
> -	return gc->get ? gc->get(gc, gpio_chip_hwgpio(desc)) : -EIO;
> +	return gpiochip_get(gc, gpio_chip_hwgpio(desc));
>  }

...

>  		for_each_set_bit(i, mask, gc->ngpio) {
> -			value = gc->get(gc, i);
> +			value = gpiochip_get(gc, i);

This will delay the function for checking every time if the get() exists. Which
must be here.

>  			if (value < 0)
>  				return value;
>  			__assign_bit(i, bits, value);

What I would expect here is something like this:

static int gpio_chip_get_value_nocheck(struct gpio_chip *gc, unsigned int offset)
{
	int ret;

	lockdep_assert_held(&gc->gpiodev->srcu);

	ret = gc->get(gc, offset);
	if (ret > GPIO_LINE_DIRECTION_IN)
		ret = -EBADE;

	return ret;
}

static int gpio_chip_get_value(struct gpio_chip *gc, const struct gpio_desc *desc)
{
	return gc->get ? gpio_chip_get_value_nocheck(gc, gpio_chip_hwgpio(desc)) : -EIO;
}

But I see the downside of it as it might lurk without RCU lock if get is not
defined. So, up to you.

-- 
With Best Regards,
Andy Shevchenko






[Index of Archives]     [Linux SPI]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux