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 13:02:26 +0300
commit883e4bbf06eb5fb7482679e4edb201093e9f55a2 (patch)
treea589e57bad0255614fe62389864cb8d9880a14ef
parent309364bc3205b36c2dd6a13ac04d1ea8b681e193 (diff)
downloadlinux-883e4bbf06eb5fb7482679e4edb201093e9f55a2.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 7037dc47ca0e..b4b71e68b90d 100644
--- a/drivers/gpio/gpiolib-cdev.c
+++ b/drivers/gpio/gpiolib-cdev.c
@@ -1243,6 +1243,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);
@@ -1254,6 +1256,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;
}