[PATCH 1/2] iio: adc: lpc32xx: Initialize completion before requesting IRQ

Vladimir Zapolskiy vz at kernel.org
Sat Jun 13 03:09:31 PDT 2026


On 6/13/26 03:58, Maxwell Doose wrote:
> In the report from Jaeyoung Chung:
> 
> "lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c registers its
> interrupt handler with devm_request_irq() before it initializes
> st->completion with init_completion(). If an interrupt arrives after
> devm_request_irq() and before init_completion(), the handler calls
> complete() on an uninitialized completion, causing a kernel panic.
> 
> The probe path, in lpc32xx_adc_probe():
> 
>      iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); /* st kzalloc-zeroed */
>      ...
>      retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
>                                LPC32XXAD_NAME, st);           /* register handler */
>      ...
>      init_completion(&st->completion);                       /* initialize completion */
> 
> lpc32xx_adc_isr() calls complete():
> 
>      complete(&st->completion);
> 
> If the device raises an interrupt before init_completion() runs,
> complete() acquires the uninitialized wait.lock and walks the zeroed
> task_list in swake_up_locked(). The zeroed task_list makes list_empty()
> return false, so swake_up_locked() dereferences a NULL list entry,
> triggering a KASAN wild-memory-access."
> 
> Fix the chance of a spurious IRQ causing an uninitialized pointer
> dereference by moving init_completion() above devm_request_irq().
> 
> Fixes: 7901b2a1453e ("staging:iio:adc:lpc32xx rename local state structure to _state")
> Reported-by: Sangyun Kim <sangyun.kim at snu.ac.kr>
> Reported-by: Kyungwook Boo <bookyungwook at gmail.com>
> Reported-by: Jaeyoung Chung <jjy600901 at snu.ac.kr>
> Closes: https://lore.kernel.org/linux-iio/20260610115700.774689-1-jjy600901@snu.ac.kr/
> Signed-off-by: Maxwell Doose <m32285159 at gmail.com>
> ---
>   drivers/iio/adc/lpc32xx_adc.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/iio/adc/lpc32xx_adc.c b/drivers/iio/adc/lpc32xx_adc.c
> index 43a7bc8158b5..db3a602327ff 100644
> --- a/drivers/iio/adc/lpc32xx_adc.c
> +++ b/drivers/iio/adc/lpc32xx_adc.c
> @@ -179,6 +179,8 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
>   	if (irq < 0)
>   		return irq;
>   
> +	init_completion(&st->completion);
> +
>   	retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
>   				  LPC32XXAD_NAME, st);
>   	if (retval < 0) {
> @@ -197,8 +199,6 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
>   
>   	platform_set_drvdata(pdev, iodev);
>   
> -	init_completion(&st->completion);
> -
>   	iodev->name = LPC32XXAD_NAME;
>   	iodev->info = &lpc32xx_adc_iio_info;
>   	iodev->modes = INDIO_DIRECT_MODE;

Reviewed-by: Vladimir Zapolskiy <vz at kernel.org>

-- 
Best wishes,
Vladimir



More information about the linux-arm-kernel mailing list