summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Gibson <warthog618@gmail.com>2024-05-10 09:53:42 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2024-05-17 12:56:15 +0300
commit1a51e24404d77bb3307c1e39eee0d8e86febb1a5 (patch)
tree5a8c8ffd34653ea212ccc982cd8beea3896c68bb
parent9ed256d2949135e1d6f44fa91750dd7c6be54e00 (diff)
downloadlinux-1a51e24404d77bb3307c1e39eee0d8e86febb1a5.tar.xz
gpiolib: cdev: fix uninitialised kfifo
[ Upstream commit ee0166b637a5e376118e9659e5b4148080f1d27e ] If a line is requested with debounce, and that results in debouncing in software, and the line is subsequently reconfigured to enable edge detection then the allocation of the kfifo to contain edge events is overlooked. This results in events being written to and read from an uninitialised kfifo. Read events are returned to userspace. Initialise the kfifo in the case where the software debounce is already active. Fixes: 65cff7046406 ("gpiolib: cdev: support setting debounce") Signed-off-by: Kent Gibson <warthog618@gmail.com> Link: https://lore.kernel.org/r/20240510065342.36191-1-warthog618@gmail.com Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/gpio/gpiolib-cdev.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c
index 6ee1074d4915..97e8335716b0 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -1201,6 +1201,8 @@ static int edge_detector_update(struct line *line,
struct gpio_v2_line_config *lc,
unsigned int line_idx, u64 edflags)
{
+ u64 eflags;
+ int ret;
u64 active_edflags = READ_ONCE(line->edflags);
unsigned int debounce_period_us =
gpio_v2_line_config_debounce_period(lc, line_idx);
@@ -1212,6 +1214,18 @@ static int edge_detector_update(struct line *line,
/* sw debounced and still will be...*/
if (debounce_period_us && READ_ONCE(line->sw_debounced)) {
line_set_debounce_period(line, debounce_period_us);
+ /*
+ * ensure event fifo is initialised if edge detection
+ * is now enabled.
+ */
+ eflags = edflags & GPIO_V2_LINE_EDGE_FLAGS;
+ if (eflags && !kfifo_initialized(&line->req->events)) {
+ ret = kfifo_alloc(&line->req->events,
+ line->req->event_buffer_size,
+ GFP_KERNEL);
+ if (ret)
+ return ret;
+ }
return 0;
}