All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nuno Sá" <nuno.sa@analog.com>
To: Fan Wu <fanwu01@zju.edu.cn>
Cc: Jonathan Cameron <jic23@kernel.org>,
	David Lechner <dlechner@baylibre.com>,
	Andy Shevchenko <andy@kernel.org>,
	linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org,
	stable@vger.kernel.org, Song Li <songl@zju.edu.cn>
Subject: Re: [PATCH] iio: adc: ad_sigma_delta: fix use-after-free on unbind
Date: Thu, 24 Sep 2026 09:45:07 +0100	[thread overview]
Message-ID: <arTioh-Dax9Ogizj@nsa> (raw)
In-Reply-To: <20260923094807.503690-1-fanwu01@zju.edu.cn>

On Wed, Sep 23, 2026 at 09:48:07AM +0000, Fan Wu wrote:
> ad_sd_buffer_postenable() allocates sigma_delta->samples_buf with
> devm_krealloc() at runtime, so its devres entry sits after all
> probe-time entries of the driver. devm resources are released in
> reverse allocation order, which means unbind frees samples_buf before
> iio_device_unregister() disables the buffers and detaches the trigger
> pollfunc. The data ready IRQ is still enabled at that point, so
> ad_sd_trigger_handler() can still run and memcpy() incoming samples
> into the freed samples_buf.
> 
> Fix this by preallocating the buffer in
> devm_ad_sd_setup_buffer_and_trigger(), before the triggered buffer and
> the IRQ are set up, so it is freed only after iio_device_unregister()
> has drained the trigger handler via free_irq(). Size it for the worst
> case of all sequencer slots being active; ad_sd_validate_scan_mask()
> already caps the number of active channels at num_slots.
> 
> This issue was found by an in-house static analysis tool.
> 
> Fixes: 8bea9af887de ("iio: adc: ad_sigma_delta: Add sequencer support")
> Cc: stable@vger.kernel.org
> Co-developed-by: Song Li <songl@zju.edu.cn>
> Signed-off-by: Song Li <songl@zju.edu.cn>
> Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
> ---

Makes sense to me! One minor nit Jonathan might be ale to tweak when
applying. With that:

Reviewed-by: Nuno Sá <nuno.sa@analog.com>

>  drivers/iio/adc/ad_sigma_delta.c | 32 +++++++++++++++++++-------------
>  1 file changed, 19 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c
> index 1b41029..4f982c6 100644
> --- a/drivers/iio/adc/ad_sigma_delta.c
> +++ b/drivers/iio/adc/ad_sigma_delta.c
> @@ -498,7 +498,6 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
>  	const struct iio_scan_type *scan_type = &indio_dev->channels[0].scan_type;
>  	struct spi_transfer *xfer = sigma_delta->sample_xfer;
>  	unsigned int i, slot, channel;
> -	u8 *samples_buf;
>  	int ret;
>  
>  	if (sigma_delta->num_slots == 1) {
> @@ -530,7 +529,7 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
>  		xfer[1].bits_per_word = scan_type->realbits;
>  		xfer[1].len = spi_bpw_to_bytes(scan_type->realbits);
>  	} else {
> -		unsigned int samples_buf_size, scan_size;
> +		unsigned int scan_size;
>  
>  		if (sigma_delta->active_slots > 1) {
>  			ret = ad_sigma_delta_append_status(sigma_delta, true);
> @@ -538,17 +537,6 @@ static int ad_sd_buffer_postenable(struct iio_dev *indio_dev)
>  				return ret;
>  		}
>  
> -		samples_buf_size =
> -			ALIGN(slot * BITS_TO_BYTES(scan_type->storagebits),
> -			      sizeof(s64));
> -		samples_buf_size += sizeof(s64);
> -		samples_buf = devm_krealloc(&sigma_delta->spi->dev,
> -					    sigma_delta->samples_buf,
> -					    samples_buf_size, GFP_KERNEL);
> -		if (!samples_buf)
> -			return -ENOMEM;
> -
> -		sigma_delta->samples_buf = samples_buf;
>  		scan_size = BITS_TO_BYTES(scan_type->realbits + scan_type->shift);
>  		/* For 24-bit data, there is an extra byte of padding. */
>  		xfer[1].rx_buf = &sigma_delta->rx_buf[scan_size == 3 ? 1 : 0];
> @@ -855,6 +843,24 @@ int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indi
>  
>  		indio_dev->setup_ops = &ad_sd_buffer_setup_ops;
>  	} else {
> +		const struct iio_scan_type *scan_type =
> +			&indio_dev->channels[0].scan_type;
> +		unsigned int samples_buf_size;
> +
> +		/*
> +		 * Worst-case size: all sequencer slots can be active, capped
> +		 * at num_slots by ad_sd_validate_scan_mask().
> +		 */
> +		samples_buf_size =
> +			ALIGN(sigma_delta->num_slots *
> +			      BITS_TO_BYTES(scan_type->storagebits),
> +			      sizeof(s64));
> +		samples_buf_size += sizeof(s64);
> +		sigma_delta->samples_buf =
> +			devm_kzalloc(dev, samples_buf_size, GFP_KERNEL);

Why the line break for devm_kzalloc(). Keep it in the same line please.
Tbh same for for the ALIGN() call but at least that one is coherent with
the original code.

- Nuno Sá

> +		if (!sigma_delta->samples_buf)
> +			return -ENOMEM;
> +
>  		ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
>  						      &iio_pollfunc_store_time,
>  						      &ad_sd_trigger_handler,
> 

  reply	other threads:[~2026-09-24  8:44 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-23  9:48 [PATCH] iio: adc: ad_sigma_delta: fix use-after-free on unbind Fan Wu
2026-09-24  8:45 ` Nuno Sá [this message]
2026-09-27 19:09   ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=arTioh-Dax9Ogizj@nsa \
    --to=nuno.sa@analog.com \
    --cc=andy@kernel.org \
    --cc=dlechner@baylibre.com \
    --cc=fanwu01@zju.edu.cn \
    --cc=jic23@kernel.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=songl@zju.edu.cn \
    --cc=stable@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.