Re: [PATCH v4] iio: health: max30102: fix NULL dereference in interrupt handler
Jonathan Cameron <[email protected]>
| Newsgroups | dev.linux.lists.linux-kernel-mentees,org.kernel.vger.linux-iio,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260810005340.638d6b1b@jic23-huawei> |
On Sat, 8 Aug 2026 15:54:50 -0400 Marco Chen <[email protected]> wrote: > 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 <[email protected]> > Signed-off-by: Marco Chen <[email protected]> Applied to the fixes-togreg branch of iio.git. Note however that this has missed my last pull request for this cycle so won't go anywhere until after rc1 which is in about 3 weeks time. thanks, Jonathan > --- > Changes in v4: > - Trim the backtrace to only relevant frames and unwrap the first line > as suggested by Andy. > > max30102_fifo_count() still has the odd name and int return you mentioned > in v2, so I will send a follow-up patch once this lands. > > Tested on a MAX30102 on Raspberry Pi 4 over I2C. > > v1: https://lore.kernel.org/linux-iio/[email protected]/ > v2: https://lore.kernel.org/linux-iio/[email protected]/ > v3: https://lore.kernel.org/linux-iio/[email protected]/ > > drivers/iio/health/max30102.c | 12 +++++++++--- > 1 file 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); >