| From 82f3015635249a8c8c45bac303fd84905066f04f Mon Sep 17 00:00:00 2001 |
| From: David Frey <dpfrey@gmail.com> |
| Date: Thu, 19 Sep 2019 15:54:18 -0700 |
| Subject: iio: light: opt3001: fix mutex unlock race |
| |
| From: David Frey <dpfrey@gmail.com> |
| |
| commit 82f3015635249a8c8c45bac303fd84905066f04f upstream. |
| |
| When an end-of-conversion interrupt is received after performing a |
| single-shot reading of the light sensor, the driver was waking up the |
| result ready queue before checking opt->ok_to_ignore_lock to determine |
| if it should unlock the mutex. The problem occurred in the case where |
| the other thread woke up and changed the value of opt->ok_to_ignore_lock |
| to false prior to the interrupt thread performing its read of the |
| variable. In this case, the mutex would be unlocked twice. |
| |
| Signed-off-by: David Frey <dpfrey@gmail.com> |
| Reviewed-by: Andreas Dannenberg <dannenberg@ti.com> |
| Fixes: 94a9b7b1809f ("iio: light: add support for TI's opt3001 light sensor") |
| Cc: <Stable@vger.kernel.org> |
| Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/iio/light/opt3001.c | 6 +++++- |
| 1 file changed, 5 insertions(+), 1 deletion(-) |
| |
| --- a/drivers/iio/light/opt3001.c |
| +++ b/drivers/iio/light/opt3001.c |
| @@ -646,6 +646,7 @@ static irqreturn_t opt3001_irq(int irq, |
| struct iio_dev *iio = _iio; |
| struct opt3001 *opt = iio_priv(iio); |
| int ret; |
| + bool wake_result_ready_queue = false; |
| |
| if (!opt->ok_to_ignore_lock) |
| mutex_lock(&opt->lock); |
| @@ -680,13 +681,16 @@ static irqreturn_t opt3001_irq(int irq, |
| } |
| opt->result = ret; |
| opt->result_ready = true; |
| - wake_up(&opt->result_ready_queue); |
| + wake_result_ready_queue = true; |
| } |
| |
| out: |
| if (!opt->ok_to_ignore_lock) |
| mutex_unlock(&opt->lock); |
| |
| + if (wake_result_ready_queue) |
| + wake_up(&opt->result_ready_queue); |
| + |
| return IRQ_HANDLED; |
| } |
| |