All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Paul E. McKenney" <paulmck@kernel.org>
To: Zqiang <qiang1.zhang@intel.com>
Cc: frederic@kernel.org, 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: Thu, 5 Jan 2023 19:41:46 -0800	[thread overview]
Message-ID: <20230106034146.GM4028633@paulmck-ThinkPad-P17-Gen-1> (raw)
In-Reply-To: <20221224052553.263199-1-qiang1.zhang@intel.com>

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)) {
+		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-06  3:41 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 [this message]
2023-01-06 12:58   ` Zhang, Qiang1
2023-01-09 13:21   ` Frederic Weisbecker
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=20230106034146.GM4028633@paulmck-ThinkPad-P17-Gen-1 \
    --to=paulmck@kernel.org \
    --cc=frederic@kernel.org \
    --cc=joel@joelfernandes.org \
    --cc=linux-kernel@vger.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.