On 19 October 2026 03:36:44 BST, [email protected] wrote:
>From: Fu Wenxin <[email protected]>
>
>Commit e4ed20c1603c ("rcutorture: Exercise DEFINE_STATIC_SRCU_FAST() and
>init_srcu_struct_fast()") split SRCU torture initialization into two
>helpers: srcu_torture_init(), which now only points srcu_ctlp at the
>static srcu_ctl/srcu_ctlf/srcu_ctlfud structures, and the new
>srcud_torture_init(), which calls init_srcu_struct(&srcu_ctld) for the
>dynamically allocated srcu_ctld.
>
>That commit updated srcud_ops to use srcud_torture_init(), but left
>busted_srcud_ops pairing .init = srcu_torture_init (static srcu_ctl) with
>.cleanup = srcu_torture_cleanup (which unconditionally calls
>cleanup_srcu_struct(&srcu_ctld)). As a result srcu_ctld is never
>initialized when running torture_type=busted_srcud, yet it is torn down
>at module unload.
>
>cleanup_srcu_struct() then dereferences ssp->srcu_sup, which is still
>NULL for the zero-initialized srcu_ctld, and faults on the ->lock field
>accessed by raw_spin_lock_irq_rcu_node():
>
>  Unable to handle kernel paging request at virtual address dfff80000000001b
>  ...
>  el1_abort -> do_translation_fault -> do_bad_area -> die_kernel_fault
>
>(The fault address is the KASAN shadow of NULL + offsetof(srcu_usage,
>lock) == 0xd8.)
>
>This is trivially reproducible:
>
>  modprobe rcutorture torture_type=busted_srcud
>  sleep 45
>  rmmod rcutorture    # panic here
>
>Fix it by making busted_srcud_ops initialize the same srcu_ctld that its
>cleanup handler tears down, matching srcud_ops.
>
>Fixes: e4ed20c1603c ("rcutorture: Exercise DEFINE_STATIC_SRCU_FAST() and 
>init_srcu_struct_fast()")

Nice catch! I reproduced this bug on my PowerPC host:

Reviewed-by: Bradley Morgan <[email protected]>

Tested-by: Bradley Morgan <[email protected]> # Power10

>Signed-off-by: Fu Wenxin <[email protected]>
>---
> kernel/rcu/rcutorture.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c
>index 8a9282a0245cc..7cc78da1356f9 100644
>--- a/kernel/rcu/rcutorture.c
>+++ b/kernel/rcu/rcutorture.c
>@@ -991,7 +991,7 @@ static struct rcu_torture_ops srcud_ops = {
> /* As above, but broken due to inappropriate reader extension. */
> static struct rcu_torture_ops busted_srcud_ops = {
>       .ttype          = SRCU_FLAVOR,
>-      .init           = srcu_torture_init,
>+      .init           = srcud_torture_init,
>       .cleanup        = srcu_torture_cleanup,
>       .readlock       = srcu_torture_read_lock,
>       .read_delay     = rcu_read_delay,
>



--- Thanks!
"I'm not a very positive person" - Linus torvalds

Reply via email to