• Zqiang's avatar
    softirq: Fix suspicious RCU usage in __do_softirq() · 1dd1eff1
    Zqiang authored
    Currently, the condition "__this_cpu_read(ksoftirqd) == current" is used to
    invoke rcu_softirq_qs() in ksoftirqd tasks context for non-RT kernels.
    
    This works correctly as long as the context is actually task context but
    this condition is wrong when:
    
         - the current task is ksoftirqd
         - the task is interrupted in a RCU read side critical section
         - __do_softirq() is invoked on return from interrupt
    
    Syzkaller triggered the following scenario:
    
      -> finish_task_switch()
        -> put_task_struct_rcu_user()
          -> call_rcu(&task->rcu, delayed_put_task_struct)
            -> __kasan_record_aux_stack()
              -> pfn_valid()
                -> rcu_read_lock_sched()
                  <interrupt>
                    __irq_exit_rcu()
                    -> __do_softirq)()
                       -> if (!IS_ENABLED(CONFIG_PREEMPT_RT) &&
                         __this_cpu_read(ksoftirqd) == current)
                         -> rcu_softirq_qs()
                           -> RCU_LOCKDEP_WARN(lock_is_held(&rcu_sched_lock_map))
    
    The rcu quiescent state is reported in the rcu-read critical section, so
    the lockdep warning is triggered.
    
    Fix this by splitting out the inner working of __do_softirq() into a helper
    function which takes an argument to distinguish between ksoftirqd task
    context and interrupted context and invoke it from the relevant call sites
    with the proper context information and use that for the conditional
    invocation of rcu_softirq_qs().
    
    Reported-by: syzbot+dce04ed6d1438ad69656@syzkaller.appspotmail.com
    Suggested-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Signed-off-by: default avatarZqiang <qiang.zhang1211@gmail.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Link: https://lore.kernel.org/r/20240427102808.29356-1-qiang.zhang1211@gmail.com
    Link: https://lore.kernel.org/lkml/8f281a10-b85a-4586-9586-5bbc12dc784f@paulmck-laptop/T/#mea8aba4abfcb97bbf499d169ce7f30c4cff1b0e3
    1dd1eff1
softirq.c 23.8 KB