diff options
| author | Marco Chen <marcochen.dev@gmail.com> | 2026-08-08 15:54:50 -0400 |
|---|---|---|
| committer | Jonathan Cameron <jonathan.cameron@oss.qualcomm.com> | 2026-08-31 00:52:39 +0100 |
| commit | f0ea4824deebf21dacfbe397c4b0a5fd3e745a8d (patch) | |
| tree | 4ada3eaf6cef7e4083d75a72cf00a4bf64fee135 /drivers | |
| parent | cee9395acd8043be0644b25c34bfa86623f2b935 (diff) | |
| download | linux-next-f0ea4824deebf21dacfbe397c4b0a5fd3e745a8d.tar.gz linux-next-f0ea4824deebf21dacfbe397c4b0a5fd3e745a8d.zip | |
iio: health: max30102: fix NULL dereference in interrupt handler
The interrupt is requested in max30102_probe() and stays enabled
for the lifetime of the device, but indio_dev->active_scan_mask is only
valid while a buffer is enabled. When an interrupt arrives while no
buffer is enabled, the handler dereferences the NULL active_scan_mask:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
Call trace:
__bitmap_weight+0x64/0x98 (P)
max30102_interrupt_handler+0x48/0x160 [max30102]
Call max30102_fifo_count() at the top of the handler and return early
unless it reports a FIFO sample is ready. Because FIFO_RDY is the only
interrupt source enabled in max30102_chip_init(), an invocation of
max30102_interrupt_handler() without the FIFO_RDY interrupt status bit
set carries no data to read and can return before touching
active_scan_mask. A negative return from max30102_fifo_count()
indicates a failed interrupt status read and is treated the same way.
Fixes: 90579b69e94b ("iio: health: max30102: Add MAX30105 support")
Suggested-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Marco Chen <marcochen.dev@gmail.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/iio/health/max30102.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/iio/health/max30102.c b/drivers/iio/health/max30102.c index c37316c86f14..aee96167f01e 100644 --- a/drivers/iio/health/max30102.c +++ b/drivers/iio/health/max30102.c @@ -290,9 +290,15 @@ static irqreturn_t max30102_interrupt_handler(int irq, void *private) { struct iio_dev *indio_dev = private; struct max30102_data *data = iio_priv(indio_dev); - unsigned int measurements = bitmap_weight(indio_dev->active_scan_mask, - iio_get_masklength(indio_dev)); - int ret, cnt = 0; + unsigned int measurements; + int ret, cnt; + + cnt = max30102_fifo_count(data); + if (cnt <= 0) + return IRQ_HANDLED; + + measurements = bitmap_weight(indio_dev->active_scan_mask, + iio_get_masklength(indio_dev)); mutex_lock(&data->lock); |
