All of lore.kernel.org
 help / color / mirror / Atom feed
From: Frederic Weisbecker <frederic@kernel.org>
To: "Paul E. McKenney" <paulmck@kernel.org>
Cc: Zqiang <qiang1.zhang@intel.com>,
	quic_neeraju@quicinc.com, joel@joelfernandes.org,
	rcu@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] rcu: Safe access to rcu_node structure's->exp_tasks
Date: Mon, 9 Jan 2023 14:21:01 +0100	[thread overview]
Message-ID: <Y7wUvZ/kVmpxvm14@lothringen> (raw)
In-Reply-To: <20230106034146.GM4028633@paulmck-ThinkPad-P17-Gen-1>

On Thu, Jan 05, 2023 at 07:41:46PM -0800, Paul E. McKenney wrote:
> On Sat, Dec 24, 2022 at 01:25:53PM +0800, Zqiang wrote:
> > For kernels built with CONFIG_PREEMPT_RCU=y, the following scenario
> > can result system oops.
> > 
> >            CPU1                                           CPU2
> > rcu_preempt_deferred_qs_irqrestore                rcu_print_task_exp_stall
> >   if (special.b.blocked)                            READ_ONCE(rnp->exp_tasks) != NULL
> >     raw_spin_lock_rcu_node
> >     np = rcu_next_node_entry(t, rnp)
> >     if (&t->rcu_node_entry == rnp->exp_tasks)
> >       WRITE_ONCE(rnp->exp_tasks, np)
> >       ....
> >       raw_spin_unlock_irqrestore_rcu_node
> >                                                     raw_spin_lock_irqsave_rcu_node
> >                                                     t = list_entry(rnp->exp_tasks->prev,
> >                                                         struct task_struct, rcu_node_entry)
> >                                                     (if rnp->exp_tasks is NULL
> >                                                        will trigger oops)
> > 
> > This problem is that CPU2 accesses rcu_node structure's->exp_tasks
> > without holding the rcu_node structure's ->lock and CPU2 did not
> > observe CPU1's change to rcu_node structure's->exp_tasks in time,
> > if rcu_node structure's->exp_tasks is set null pointer by CPU1, after
> > that CPU2 accesses members of rcu_node structure's->exp_tasks will
> > trigger oops.
> > 
> > This commit therefore allows rcu_node structure's->exp_tasks to be
> > accessed while holding rcu_node structure's ->lock.
> > 
> > Signed-off-by: Zqiang <qiang1.zhang@intel.com>
> 
> Apologies for the delay and thank you for the reminder!
> 
> Please check the wordsmithed version below, which I have queued.
> 
> 						Thanx, Paul
> 
> ------------------------------------------------------------------------
> 
> commit 389b0eafd72829fd63548f7ff4e8d6ac90fa1f98
> Author: Zqiang <qiang1.zhang@intel.com>
> Date:   Sat Dec 24 13:25:53 2022 +0800
> 
>     rcu: Protect rcu_print_task_exp_stall() ->exp_tasks access
>     
>     For kernels built with CONFIG_PREEMPT_RCU=y, the following scenario can
>     result in a NULL-pointer dereference:
>     
>                CPU1                                           CPU2
>     rcu_preempt_deferred_qs_irqrestore                rcu_print_task_exp_stall
>       if (special.b.blocked)                            READ_ONCE(rnp->exp_tasks) != NULL
>         raw_spin_lock_rcu_node
>         np = rcu_next_node_entry(t, rnp)
>         if (&t->rcu_node_entry == rnp->exp_tasks)
>           WRITE_ONCE(rnp->exp_tasks, np)
>           ....
>           raw_spin_unlock_irqrestore_rcu_node
>                                                         raw_spin_lock_irqsave_rcu_node
>                                                         t = list_entry(rnp->exp_tasks->prev,
>                                                             struct task_struct, rcu_node_entry)
>                                                         (if rnp->exp_tasks is NULL, this
>                                                            will dereference a NULL pointer)
>     
>     The problem is that CPU2 accesses the rcu_node structure's->exp_tasks
>     field without holding the rcu_node structure's ->lock and CPU2 did
>     not observe CPU1's change to rcu_node structure's ->exp_tasks in time.
>     Therefore, if CPU1 sets rcu_node structure's->exp_tasks pointer to NULL,
>     then CPU2 might dereference that NULL pointer.
>     
>     This commit therefore holds the rcu_node structure's ->lock while
>     accessing that structure's->exp_tasks field.
>     
>     Signed-off-by: Zqiang <qiang1.zhang@intel.com>
>     Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
> 
> diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h
> index 7cc4856da0817..902e7c8709c7e 100644
> --- a/kernel/rcu/tree_exp.h
> +++ b/kernel/rcu/tree_exp.h
> @@ -803,9 +803,11 @@ static int rcu_print_task_exp_stall(struct rcu_node *rnp)
>  	int ndetected = 0;
>  	struct task_struct *t;
>  
> -	if (!READ_ONCE(rnp->exp_tasks))
> -		return 0;
>  	raw_spin_lock_irqsave_rcu_node(rnp, flags);
> +	if (!READ_ONCE(rnp->exp_tasks)) {

Does it have to be READ_ONCE then?

Thanks.

> +		raw_spin_unlock_irqrestore_rcu_node(rnp, flags);
> +		return 0;
> +	}
>  	t = list_entry(rnp->exp_tasks->prev,
>  		       struct task_struct, rcu_node_entry);
>  	list_for_each_entry_continue(t, &rnp->blkd_tasks, rcu_node_entry) {

  parent reply	other threads:[~2023-01-09 13:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-24  5:25 [PATCH] rcu: Safe access to rcu_node structure's->exp_tasks Zqiang
2023-01-06  3:10 ` Zhang, Qiang1
2023-01-06  3:41 ` Paul E. McKenney
2023-01-06 12:58   ` Zhang, Qiang1
2023-01-09 13:21   ` Frederic Weisbecker [this message]
2023-01-09 15:22     ` Paul E. McKenney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Y7wUvZ/kVmpxvm14@lothringen \
    --to=frederic@kernel.org \
    --cc=joel@joelfernandes.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=paulmck@kernel.org \
    --cc=qiang1.zhang@intel.com \
    --cc=quic_neeraju@quicinc.com \
    --cc=rcu@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.