diff options
author | Eddy Wu <itseddy0402@gmail.com> | 2020-11-07 14:47:22 +0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-11-10 12:36:00 +0100 |
commit | b177d2d915cea2d0a590f0034a20299dd1ee3ef2 (patch) | |
tree | 8a7b82ea2a82f6d89eab1f127293fd31338a9da6 | |
parent | 6612b754ac0c85ca8b1181b5d3ea4461a8c1bbcb (diff) | |
download | linux-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>
-rw-r--r-- | kernel/fork.c | 10 |
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); |