Re: [PATCH v12 3/3] gpio: Leverage revocable for accessing struct gpio_chip
From: Bartosz Golaszewski
Date: Thu Sep 10 2026 - 03:42:03 EST
On Tue, 8 Sep 2026 15:42:23 +0200, Tzung-Bi Shih <tzungbi@xxxxxxxxxx> said:
> The underlying chip can be removed asynchronously. `gdev->srcu` is used
> to ensure the synchronization before accessing `gdev->chip`.
>
> Revocable encapsulates the details. Leverage revocable for accessing
> the struct gpio_chip and remove the `gdev->srcu`.
>
> Tested-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxxxxxxxx>
> Signed-off-by: Tzung-Bi Shih <tzungbi@xxxxxxxxxx>
> ---
Could you address the following issue pointed out by sashiko?
> diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
> index 66d2325bfae87..a7d3c4d9018c8 100644
> --- a/drivers/gpio/gpiolib.c
> +++ b/drivers/gpio/gpiolib.c
> @@ -898,10 +897,10 @@ static void gpiodev_release(struct device *dev)
> synchronize_srcu(&gdev->desc_srcu);
> cleanup_srcu_struct(&gdev->desc_srcu);
>
> + revocable_put(&gdev->chip_rev);
> ida_free(&gpio_ida, gdev->id);
> kfree_const(gdev->label);
> kfree(gdev->descs);
> - cleanup_srcu_struct(&gdev->srcu);
> kfree(gdev);
> }
Could this cause a use-after-free crash during concurrent device removal?
The revocable object chip_rev is embedded directly in the gpio_device struct.
The new access cleanup pattern drops the SRCU lock before dropping the kref
on the revocable object.
During asynchronous device removal, revocable_revoke() executes
synchronize_srcu() to wait for readers. Because the reader drops the SRCU lock
first, revocable_revoke() will unblock, proceed to gpio_device_put(gdev), and
gpiodev_release() will execute kfree(gdev) while the reader thread is still
active.
The reader thread will then attempt to call kref_put() on the chip_rev that is
embedded inside the now-freed gdev.
--
Thanks,
Bartosz