diff options
author | Kent Gibson <warthog618@gmail.com> | 2024-05-29 15:19:51 +0200 |
---|---|---|
committer | Bartosz Golaszewski <bartosz.golaszewski@linaro.org> | 2024-05-30 11:29:10 +0200 |
commit | 35d848e7a1cbba2649ed98cf58e0cdc7ee560c7a (patch) | |
tree | 6d648ee553cdf6d6d64b90f0f8a4ea1cc559784a /drivers/gpio | |
parent | gpio: rdc321x: Convert PCIBIOS_* return codes to errnos (diff) | |
download | linux-35d848e7a1cbba2649ed98cf58e0cdc7ee560c7a.tar.xz linux-35d848e7a1cbba2649ed98cf58e0cdc7ee560c7a.zip |
gpiolib: cdev: Add INIT_KFIFO() for linereq events
The initialisation of the linereq events kfifo relies on the struct being
zeroed and a subsequent call to kfifo_alloc(). The call to kfifo_alloc()
is deferred until edge detection is first enabled for the linereq. If the
kfifo is inadvertently accessed before the call to kfifo_alloc(), as was
the case in a recently discovered bug, it behaves as a FIFO of size 1 with
an element size of 0, so writes and reads to the kfifo appear successful
but copy no actual data.
As a defensive measure, initialise the kfifo with INIT_KFIFO() when the
events kfifo is constructed. This initialises the kfifo element size
and zeroes its data pointer, so any inadvertant access prior to the
kfifo_alloc() call will trigger an oops.
Signed-off-by: Kent Gibson <warthog618@gmail.com>
Link: https://lore.kernel.org/r/20240529131953.195777-2-warthog618@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Diffstat (limited to 'drivers/gpio')
-rw-r--r-- | drivers/gpio/gpiolib-cdev.c | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index 9dad67ea2597..d4e47960cc98 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c @@ -1774,6 +1774,7 @@ static int linereq_create(struct gpio_device *gdev, void __user *ip) mutex_init(&lr->config_mutex); init_waitqueue_head(&lr->wait); + INIT_KFIFO(lr->events); lr->event_buffer_size = ulr.event_buffer_size; if (lr->event_buffer_size == 0) lr->event_buffer_size = ulr.num_lines * 16; |