summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorEddy Wu <itseddy0402@gmail.com>2020-11-07 14:47:22 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-11-10 12:36:00 +0100
commitb177d2d915cea2d0a590f0034a20299dd1ee3ef2 (patch)
tree8a7b82ea2a82f6d89eab1f127293fd31338a9da6 /kernel
parent6612b754ac0c85ca8b1181b5d3ea4461a8c1bbcb (diff)
downloadlinux-stable-b177d2d915cea2d0a590f0034a20299dd1ee3ef2.tar.gz
linux-stable-b177d2d915cea2d0a590f0034a20299dd1ee3ef2.tar.bz2
linux-stable-b177d2d915cea2d0a590f0034a20299dd1ee3ef2.zip
fork: fix copy_process(CLONE_PARENT) race with the exiting ->real_parent
commit b4e00444cab4c3f3fec876dc0cccc8cbb0d1a948 upstream. current->group_leader->exit_signal may change during copy_process() if current->real_parent exits. Move the assignment inside tasklist_lock to avoid the race. Signed-off-by: Eddy Wu <eddy_wu@trendmicro.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 3ed29bf8eb29..f2c92c100194 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1965,14 +1965,9 @@ static __latent_entropy struct task_struct *copy_process(
/* ok, now we should be set up.. */
p->pid = pid_nr(pid);
if (clone_flags & CLONE_THREAD) {
- p->exit_signal = -1;
p->group_leader = current->group_leader;
p->tgid = current->tgid;
} else {
- if (clone_flags & CLONE_PARENT)
- p->exit_signal = current->group_leader->exit_signal;
- else
- p->exit_signal = (clone_flags & CSIGNAL);
p->group_leader = p;
p->tgid = p->pid;
}
@@ -2017,9 +2012,14 @@ static __latent_entropy struct task_struct *copy_process(
if (clone_flags & (CLONE_PARENT|CLONE_THREAD)) {
p->real_parent = current->real_parent;
p->parent_exec_id = current->parent_exec_id;
+ if (clone_flags & CLONE_THREAD)
+ p->exit_signal = -1;
+ else
+ p->exit_signal = current->group_leader->exit_signal;
} else {
p->real_parent = current;
p->parent_exec_id = current->self_exec_id;
+ p->exit_signal = (clone_flags & CSIGNAL);
}
klp_copy_process(p);