Skip to content

Commit f747c7e

Browse files
committed
rcu-tasks: Enclose task-list scan in rcu_read_lock()
The rcu_tasks_trace_postgp() function uses for_each_process_thread() to scan the task list without the benefit of RCU read-side protection, which can result in use-after-free errors on task_struct structures. This error was missed because the TRACE01 rcutorture scenario enables lockdep, but also builds with CONFIG_PREEMPT_NONE=y. In this situation, preemption is disabled everywhere, so lockdep thinks everywhere can be a legitimate RCU reader. This commit therefore adds the needed rcu_read_lock() and rcu_read_unlock(). Note that this bug can occur only after an RCU Tasks Trace CPU stall warning, which by default only happens after a grace period has extended for ten minutes (yes, not a typo, minutes). Fixes: 4593e77 ("rcu-tasks: Add stall warnings for RCU Tasks Trace") Cc: Alexei Starovoitov <[email protected]> Cc: Daniel Borkmann <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: <[email protected]> Cc: <[email protected]> # 5.7.x Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 592031c commit f747c7e

File tree

1 file changed

+2
-0
lines changed

1 file changed

+2
-0
lines changed

kernel/rcu/tasks.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,9 +1088,11 @@ static void rcu_tasks_trace_postgp(struct rcu_tasks *rtp)
10881088
if (ret)
10891089
break; // Count reached zero.
10901090
// Stall warning time, so make a list of the offenders.
1091+
rcu_read_lock();
10911092
for_each_process_thread(g, t)
10921093
if (READ_ONCE(t->trc_reader_special.b.need_qs))
10931094
trc_add_holdout(t, &holdouts);
1095+
rcu_read_unlock();
10941096
firstreport = true;
10951097
list_for_each_entry_safe(t, g, &holdouts, trc_holdout_list) {
10961098
if (READ_ONCE(t->trc_reader_special.b.need_qs))

0 commit comments

Comments
 (0)