mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
pid_namespace: avoid optimization of accesses to ->child_reaper
To avoid potential problems related to cpu/compiler optimizations around ->child_reaper, let's use WRITE_ONCE (additional to task_list lock) everywhere we write it and use READ_ONCE where we read it without explicit lock. Note: It also pairs with existing READ_ONCE with no lock in nsfs_fh_to_dentry(). Also let's add ASSERT_EXCLUSIVE_WRITER before write to identify to KCSAN that we don't expect any concurrent ->child_reaper modifications, and those must be detected. -- Suggested-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com> Link: https://patch.msgid.link/20260318122157.280595-2-ptikhomirov@virtuozzo.com v3: Split from main commit. Add ASSERT_EXCLUSIVE_WRITER. v5: Add one more READ_ONCE for access without lock in free_pid(). Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
committed by
Christian Brauner
parent
1f318b96cc
commit
d9c857aee2
@@ -608,7 +608,8 @@ static struct task_struct *find_child_reaper(struct task_struct *father,
|
||||
|
||||
reaper = find_alive_thread(father);
|
||||
if (reaper) {
|
||||
pid_ns->child_reaper = reaper;
|
||||
ASSERT_EXCLUSIVE_WRITER(pid_ns->child_reaper);
|
||||
WRITE_ONCE(pid_ns->child_reaper, reaper);
|
||||
return reaper;
|
||||
}
|
||||
|
||||
|
||||
@@ -2423,7 +2423,10 @@ __latent_entropy struct task_struct *copy_process(
|
||||
init_task_pid(p, PIDTYPE_SID, task_session(current));
|
||||
|
||||
if (is_child_reaper(pid)) {
|
||||
ns_of_pid(pid)->child_reaper = p;
|
||||
struct pid_namespace *ns = ns_of_pid(pid);
|
||||
|
||||
ASSERT_EXCLUSIVE_WRITER(ns->child_reaper);
|
||||
WRITE_ONCE(ns->child_reaper, p);
|
||||
p->signal->flags |= SIGNAL_UNKILLABLE;
|
||||
}
|
||||
p->signal->shared_pending.signal = delayed.signal;
|
||||
|
||||
@@ -128,7 +128,7 @@ void free_pid(struct pid *pid)
|
||||
* is the reaper wake up the reaper. The reaper
|
||||
* may be sleeping in zap_pid_ns_processes().
|
||||
*/
|
||||
wake_up_process(ns->child_reaper);
|
||||
wake_up_process(READ_ONCE(ns->child_reaper));
|
||||
break;
|
||||
case PIDNS_ADDING:
|
||||
/* Handle a fork failure of the first process */
|
||||
@@ -219,7 +219,7 @@ struct pid *alloc_pid(struct pid_namespace *ns, pid_t *arg_set_tid,
|
||||
* Also fail if a PID != 1 is requested and
|
||||
* no PID 1 exists.
|
||||
*/
|
||||
if (tid != 1 && !tmp->child_reaper)
|
||||
if (tid != 1 && !READ_ONCE(tmp->child_reaper))
|
||||
goto out_abort;
|
||||
retval = -EPERM;
|
||||
if (!checkpoint_restore_ns_capable(tmp->user_ns))
|
||||
|
||||
Reference in New Issue
Block a user