* 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-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
* 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
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