Re: [PATCH 08/15] iio: light: apds9306: push events to the IIO device

From: Jonathan Cameron

Date: Sat Oct 31 2026 - 22:20:47 EST


On Tue, 27 Oct 2026 17:19:12 +0100
Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> wrote:

> From: Josef Bacik <josef@xxxxxxxxxxxxxx>
>
> Reading a light channel while threshold events are enabled can push an
> event through a pointer that is not an IIO device, corrupting memory or
> crashing the kernel.
>
> apds9306_read_data() derives indio_dev with dev_to_iio_dev(data->dev),
> but data->dev is the I2C client's device, not the device embedded in
> struct iio_dev. When the status register read by the poll loop has
> APDS9306_ALS_INT_STAT_MASK set, the bogus pointer is passed to
> iio_push_event() and iio_get_time_ns(), which dereference the event
> interface and clock id of a structure that does not exist.
>
> The bug was found by code inspection and has not been reproduced.
>
> Fix by taking the IIO device from the I2C client's driver data, which
> probe sets with i2c_set_clientdata().

I'd rather we just passed in the iio_dev given the caller always has
it anyway. Pass that instead of struct apds9306_data *data and
use iio_priv() in here to get that locally.


>
> Fixes: 620d1e6c7a3f ("iio: light: Add support for APDS9306 Light Sensor")
> Cc: stable <stable@xxxxxxxxxx>
> Cc: Subhajit Ghosh <subhajit.ghosh@xxxxxxxxxxxxxx>
> Cc: David Lechner <dlechner@xxxxxxxxxxxx>
> Cc: "Nuno Sá" <nuno.sa@xxxxxxxxxx>
> Cc: Andy Shevchenko <andy@xxxxxxxxxx>
> Signed-off-by: Josef Bacik <josef@xxxxxxxxxxxxxx>
> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx>
> ---
> drivers/iio/light/apds9306.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/iio/light/apds9306.c b/drivers/iio/light/apds9306.c
> index 7dd41136734f..79138422221d 100644
> --- a/drivers/iio/light/apds9306.c
> +++ b/drivers/iio/light/apds9306.c
> @@ -462,7 +462,7 @@ static int apds9306_power_state(struct apds9306_data *data, bool state)
> static int apds9306_read_data(struct apds9306_data *data, int *val, int reg)
> {
> struct device *dev = data->dev;
> - struct iio_dev *indio_dev = dev_to_iio_dev(dev);
> + struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct apds9306_regfields *rf = &data->rf;
> u64 ev_code;
> int ret, delay, intg_time, intg_time_idx, repeat_rate_idx, int_src;
>