[PATCH 6/8] gpiolib: actually protect the line event kfifo with mutex

From: Bartosz Golaszewski
Date: Wed Nov 27 2019 - 08:35:34 EST


From: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>

The read_lock mutex is supposed to prevent collisions between reading
and writing to the line event kfifo but it's actually only taken when
the events are being read from it. Also take the lock when adding the
events and checking if kfifo is empty.

Signed-off-by: Bartosz Golaszewski <bgolaszewski@xxxxxxxxxxxx>
---
drivers/gpio/gpiolib.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 17796437d7be..d094b1be334d 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -818,8 +818,10 @@ static __poll_t lineevent_poll(struct file *filep,

poll_wait(filep, &le->wait, wait);

+ mutex_lock(&le->read_lock);
if (!kfifo_is_empty(&le->events))
events = EPOLLIN | EPOLLRDNORM;
+ mutex_unlock(&le->read_lock);

return events;
}
@@ -838,7 +840,9 @@ static ssize_t lineevent_read(struct file *filep,
return -EINVAL;

do {
+ mutex_lock(&le->read_lock);
if (kfifo_is_empty(&le->events)) {
+ mutex_unlock(&le->read_lock);
if (filep->f_flags & O_NONBLOCK)
return -EAGAIN;

@@ -846,6 +850,8 @@ static ssize_t lineevent_read(struct file *filep,
!kfifo_is_empty(&le->events));
if (ret)
return ret;
+ } else {
+ mutex_unlock(&le->read_lock);
}

if (mutex_lock_interruptible(&le->read_lock))
@@ -969,7 +975,9 @@ static irqreturn_t lineevent_irq_thread(int irq, void *p)
return IRQ_NONE;
}

+ mutex_lock(&le->read_lock);
ret = kfifo_put(&le->events, ge);
+ mutex_unlock(&le->read_lock);
if (ret)
wake_up_poll(&le->wait, EPOLLIN);

--
2.23.0