Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* iio: adc: KASAN wild-memory-access in complete() on early IRQ
@ 2026-06-10 11:57 Jaeyoung Chung
  2026-06-11 16:07 ` Maxwell Doose
  2026-06-11 16:22 ` Jonathan Cameron
  0 siblings, 2 replies; 4+ messages in thread
From: Jaeyoung Chung @ 2026-06-10 11:57 UTC (permalink / raw)
  To: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Vladimir Zapolskiy, Piotr Wojtaszczyk
  Cc: Jaeyoung Chung, linux-iio, linux-arm-kernel, linux-kernel,
	Sangyun Kim, Kyungwook Boo

Hi,

lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c and
spear_adc_probe() in drivers/iio/adc/spear_adc.c register their
interrupt handler with devm_request_irq() before they initialize
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 */

spear_adc_probe() has the same ordering: devm_request_irq() for
spear_adc_isr() before init_completion(&st->completion).

Both interrupt handlers, lpc32xx_adc_isr() and spear_adc_isr(), call
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.

Suggested fix: move init_completion(&st->completion) above
devm_request_irq(), so the completion is valid before the handler can run.

Reported-by: Sangyun Kim <sangyun.kim@snu.ac.kr>
Reported-by: Kyungwook Boo <bookyungwook@gmail.com>

Thanks,
Jaeyoung Chung


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: iio: adc: KASAN wild-memory-access in complete() on early IRQ
  2026-06-10 11:57 iio: adc: KASAN wild-memory-access in complete() on early IRQ Jaeyoung Chung
@ 2026-06-11 16:07 ` Maxwell Doose
  2026-06-11 17:50   ` Vladimir Zapolskiy
  2026-06-11 16:22 ` Jonathan Cameron
  1 sibling, 1 reply; 4+ messages in thread
From: Maxwell Doose @ 2026-06-11 16:07 UTC (permalink / raw)
  To: Jaeyoung Chung
  Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Vladimir Zapolskiy, Piotr Wojtaszczyk, linux-iio,
	linux-arm-kernel, linux-kernel, Sangyun Kim, Kyungwook Boo

On Wed, Jun 10, 2026 at 7:04 AM Jaeyoung Chung <jjy600901@snu.ac.kr> wrote:
>
> Hi,
>
> lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c and
> spear_adc_probe() in drivers/iio/adc/spear_adc.c register their
> interrupt handler with devm_request_irq() before they initialize
> 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 */
>
> spear_adc_probe() has the same ordering: devm_request_irq() for
> spear_adc_isr() before init_completion(&st->completion).
>
> Both interrupt handlers, lpc32xx_adc_isr() and spear_adc_isr(), call
> 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.
>
> Suggested fix: move init_completion(&st->completion) above
> devm_request_irq(), so the completion is valid before the handler can run.
>
> Reported-by: Sangyun Kim <sangyun.kim@snu.ac.kr>
> Reported-by: Kyungwook Boo <bookyungwook@gmail.com>
>

Thanks for reporting this; I can start working on a fix shortly
(assuming nobody else is already working on it).


--
best regards,
max


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: iio: adc: KASAN wild-memory-access in complete() on early IRQ
  2026-06-10 11:57 iio: adc: KASAN wild-memory-access in complete() on early IRQ Jaeyoung Chung
  2026-06-11 16:07 ` Maxwell Doose
@ 2026-06-11 16:22 ` Jonathan Cameron
  1 sibling, 0 replies; 4+ messages in thread
From: Jonathan Cameron @ 2026-06-11 16:22 UTC (permalink / raw)
  To: Jaeyoung Chung
  Cc: David Lechner, Nuno Sá, Andy Shevchenko, Vladimir Zapolskiy,
	Piotr Wojtaszczyk, linux-iio, linux-arm-kernel, linux-kernel,
	Sangyun Kim, Kyungwook Boo

On Wed, 10 Jun 2026 20:57:00 +0900
Jaeyoung Chung <jjy600901@snu.ac.kr> wrote:

> Hi,
> 
> lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c and
> spear_adc_probe() in drivers/iio/adc/spear_adc.c register their
> interrupt handler with devm_request_irq() before they initialize
> 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 */
> 
> spear_adc_probe() has the same ordering: devm_request_irq() for
> spear_adc_isr() before init_completion(&st->completion).
> 
> Both interrupt handlers, lpc32xx_adc_isr() and spear_adc_isr(), call
> 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.
> 
> Suggested fix: move init_completion(&st->completion) above
> devm_request_irq(), so the completion is valid before the handler can run.
> 
> Reported-by: Sangyun Kim <sangyun.kim@snu.ac.kr>
> Reported-by: Kyungwook Boo <bookyungwook@gmail.com>

Hi I think the report is valid, but I'm curious to whether you ran these
drivers given the hardware is pretty obscure!  If not how did KASAN detect
anything (unless there is a static analysis version I'm not aware of)

Given age of drivers and that this only occurs if a spurious IRQ turns
up I'm not going to rush to fix this.  However, I'd certainly welcome
patches.

Thanks,

Jonathan


> 
> Thanks,
> Jaeyoung Chung



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: iio: adc: KASAN wild-memory-access in complete() on early IRQ
  2026-06-11 16:07 ` Maxwell Doose
@ 2026-06-11 17:50   ` Vladimir Zapolskiy
  0 siblings, 0 replies; 4+ messages in thread
From: Vladimir Zapolskiy @ 2026-06-11 17:50 UTC (permalink / raw)
  To: Maxwell Doose, Jaeyoung Chung
  Cc: Jonathan Cameron, David Lechner, Nuno Sá, Andy Shevchenko,
	Piotr Wojtaszczyk, linux-iio, linux-arm-kernel, linux-kernel,
	Sangyun Kim, Kyungwook Boo

On 6/11/26 19:07, Maxwell Doose wrote:
> On Wed, Jun 10, 2026 at 7:04 AM Jaeyoung Chung <jjy600901@snu.ac.kr> wrote:
>>
>> Hi,
>>
>> lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c and
>> spear_adc_probe() in drivers/iio/adc/spear_adc.c register their
>> interrupt handler with devm_request_irq() before they initialize
>> 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 */
>>
>> spear_adc_probe() has the same ordering: devm_request_irq() for
>> spear_adc_isr() before init_completion(&st->completion).
>>
>> Both interrupt handlers, lpc32xx_adc_isr() and spear_adc_isr(), call
>> 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.
>>
>> Suggested fix: move init_completion(&st->completion) above
>> devm_request_irq(), so the completion is valid before the handler can run.
>>
>> Reported-by: Sangyun Kim <sangyun.kim@snu.ac.kr>
>> Reported-by: Kyungwook Boo <bookyungwook@gmail.com>
>>
> 
> Thanks for reporting this; I can start working on a fix shortly
> (assuming nobody else is already working on it).
> 

The analysis and the proposed fix are correct, please go ahead, thank you
in advance.

-- 
Best wishes,
Vladimir



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-11 17:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-10 11:57 iio: adc: KASAN wild-memory-access in complete() on early IRQ Jaeyoung Chung
2026-06-11 16:07 ` Maxwell Doose
2026-06-11 17:50   ` Vladimir Zapolskiy
2026-06-11 16:22 ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox