diff options
author | Oleg Nesterov <oleg@redhat.com> | 2012-03-19 12:03:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-20 17:16:50 -0400 |
commit | b6e238dceed36891cc633167afe7151f1f3d83c5 (patch) | |
tree | eef4928c1a0cb1b56eb20f8d0ee592709d533f10 /kernel/signal.c | |
parent | e636825346b36a07ccfc8e30946d52855e21f681 (diff) |
exit_signal: fix the "parent has changed security domain" logic
exit_notify() changes ->exit_signal if the parent already did exec.
This doesn't really work, we are not going to send the signal now
if there is another live thread or the exiting task is traced. The
parent can exec before the last dies or the tracer detaches.
Move this check into do_notify_parent() which actually sends the
signal.
The user-visible change is that we do not change ->exit_signal,
and thus the exiting task is still "clone children" for
do_wait()->eligible_child(__WCLONE). Hopefully this is fine, the
current logic is racy anyway.
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 9 |
1 files changed, 9 insertions, 0 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 8511e39813c7..e76001ccf5cd 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1652,6 +1652,15 @@ bool do_notify_parent(struct task_struct *tsk, int sig) | |||
1652 | BUG_ON(!tsk->ptrace && | 1652 | BUG_ON(!tsk->ptrace && |
1653 | (tsk->group_leader != tsk || !thread_group_empty(tsk))); | 1653 | (tsk->group_leader != tsk || !thread_group_empty(tsk))); |
1654 | 1654 | ||
1655 | if (sig != SIGCHLD) { | ||
1656 | /* | ||
1657 | * This is only possible if parent == real_parent. | ||
1658 | * Check if it has changed security domain. | ||
1659 | */ | ||
1660 | if (tsk->parent_exec_id != tsk->parent->self_exec_id) | ||
1661 | sig = SIGCHLD; | ||
1662 | } | ||
1663 | |||
1655 | info.si_signo = sig; | 1664 | info.si_signo = sig; |
1656 | info.si_errno = 0; | 1665 | info.si_errno = 0; |
1657 | /* | 1666 | /* |