lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Mon, 28 Apr 2014 02:11:22 +0100 From: Ben Hutchings <ben@...adent.org.uk> To: linux-kernel@...r.kernel.org, stable@...r.kernel.org CC: akpm@...ux-foundation.org, "Michal Schmidt" <mschmidt@...hat.com>, "Lennart Poettering" <lpoetter@...hat.com>, "Oleg Nesterov" <oleg@...hat.com>, "Jan Kratochvil" <jan.kratochvil@...hat.com>, "Tejun Heo" <tj@...nel.org>, "Linus Torvalds" <torvalds@...ux-foundation.org>, "Roland McGrath" <roland@...k.frob.com>, "Al Viro" <viro@...IV.linux.org.uk> Subject: [PATCH 3.2 82/94] wait: fix reparent_leader() vs EXIT_DEAD->EXIT_ZOMBIE race 3.2.58-rc1 review patch. If anyone has any objections, please let me know. ------------------ From: Oleg Nesterov <oleg@...hat.com> commit dfccbb5e49a621c1b21a62527d61fc4305617aca upstream. wait_task_zombie() first does EXIT_ZOMBIE->EXIT_DEAD transition and drops tasklist_lock. If this task is not the natural child and it is traced, we change its state back to EXIT_ZOMBIE for ->real_parent. The last transition is racy, this is even documented in 50b8d257486a "ptrace: partially fix the do_wait(WEXITED) vs EXIT_DEAD->EXIT_ZOMBIE race". wait_consider_task() tries to detect this transition and clear ->notask_error but we can't rely on ptrace_reparented(), debugger can exit and do ptrace_unlink() before its sub-thread sets EXIT_ZOMBIE. And there is another problem which were missed before: this transition can also race with reparent_leader() which doesn't reset >exit_signal if EXIT_DEAD, assuming that this task must be reaped by someone else. So the tracee can be re-parented with ->exit_signal != SIGCHLD, and if /sbin/init doesn't use __WALL it becomes unreapable. Change reparent_leader() to update ->exit_signal even if EXIT_DEAD. Note: this is the simple temporary hack for -stable, it doesn't try to solve all problems, it will be reverted by the next changes. Signed-off-by: Oleg Nesterov <oleg@...hat.com> Reported-by: Jan Kratochvil <jan.kratochvil@...hat.com> Reported-by: Michal Schmidt <mschmidt@...hat.com> Tested-by: Michal Schmidt <mschmidt@...hat.com> Cc: Al Viro <viro@...IV.linux.org.uk> Cc: Lennart Poettering <lpoetter@...hat.com> Cc: Roland McGrath <roland@...k.frob.com> Cc: Tejun Heo <tj@...nel.org> Signed-off-by: Andrew Morton <akpm@...ux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@...ux-foundation.org> Signed-off-by: Ben Hutchings <ben@...adent.org.uk> --- kernel/exit.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) --- a/kernel/exit.c +++ b/kernel/exit.c @@ -734,9 +734,6 @@ static void reparent_leader(struct task_ struct list_head *dead) { list_move_tail(&p->sibling, &p->real_parent->children); - - if (p->exit_state == EXIT_DEAD) - return; /* * If this is a threaded reparent there is no need to * notify anyone anything has happened. @@ -744,9 +741,19 @@ static void reparent_leader(struct task_ if (same_thread_group(p->real_parent, father)) return; - /* We don't want people slaying init. */ + /* + * We don't want people slaying init. + * + * Note: we do this even if it is EXIT_DEAD, wait_task_zombie() + * can change ->exit_state to EXIT_ZOMBIE. If this is the final + * state, do_notify_parent() was already called and ->exit_signal + * doesn't matter. + */ p->exit_signal = SIGCHLD; + if (p->exit_state == EXIT_DEAD) + return; + /* If it has exited notify the new parent about this child's death. */ if (!p->ptrace && p->exit_state == EXIT_ZOMBIE && thread_group_empty(p)) { -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists