Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751604AbdFFTQt (ORCPT ); Tue, 6 Jun 2017 15:16:49 -0400 Received: from out01.mta.xmission.com ([166.70.13.231]:50537 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751902AbdFFTOi (ORCPT ); Tue, 6 Jun 2017 15:14:38 -0400 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-api@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Ingo Molnar , Thomas Gleixner , Kees Cook , Roland McGrath , Al Viro , David Howells , "Michael Kerrisk (man-pages)" , "Eric W. Biederman" Date: Tue, 6 Jun 2017 14:03:34 -0500 Message-Id: <20170606190338.28347-22-ebiederm@xmission.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20170606190338.28347-1-ebiederm@xmission.com> References: <877f0pym71.fsf@xmission.com> <20170606190338.28347-1-ebiederm@xmission.com> X-XM-SPF: eid=1dIJvU-0006wd-6C;;;mid=<20170606190338.28347-22-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=97.121.81.159;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1/yVw+Yz8CvHtslF2IHoeaMGTMYJdfO07I= X-SA-Exim-Connect-IP: 97.121.81.159 X-SA-Exim-Mail-From: ebiederm@xmission.com X-Spam-Report: * -1.0 ALL_TRUSTED Passed through trusted hosts only via SMTP * 0.0 TVD_RCVD_IP Message was received from an IP address * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.0 T_TM2_M_HEADER_IN_MSG BODY: No description available. * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.5000] * -0.0 DCC_CHECK_NEGATIVE Not listed in DCC * [sa05 1397; Body=1 Fuz1=1 Fuz2=1] * 0.0 T_TooManySym_01 4+ unique symbols in subject * 1.0 XMSubMetaSx_00 1+ Sexy Words * 0.0 T_FILL_THIS_FORM_SHORT Fill in a short form with personal * information X-Spam-DCC: XMission; sa05 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: **;linux-kernel@vger.kernel.org X-Spam-Relay-Country: X-Spam-Timing: total 5552 ms - load_scoreonly_sql: 0.05 (0.0%), signal_user_changed: 6 (0.1%), b_tie_ro: 5 (0.1%), parse: 1.33 (0.0%), extract_message_metadata: 16 (0.3%), get_uri_detail_list: 3.3 (0.1%), tests_pri_-1000: 8 (0.1%), tests_pri_-950: 1.36 (0.0%), tests_pri_-900: 1.15 (0.0%), tests_pri_-400: 31 (0.6%), check_bayes: 30 (0.5%), b_tokenize: 12 (0.2%), b_tok_get_all: 9 (0.2%), b_comp_prob: 2.7 (0.0%), b_tok_touch_all: 4.0 (0.1%), b_finish: 0.64 (0.0%), tests_pri_0: 266 (4.8%), check_dkim_signature: 0.59 (0.0%), check_dkim_adsp: 2.9 (0.1%), tests_pri_500: 5218 (94.0%), poll_dns_idle: 5208 (93.8%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH 22/26] exit: Fix auto-wait of ptraced children X-Spam-Flag: No X-SA-Exim-Version: 4.2.1 (built Thu, 05 May 2016 13:38:54 -0600) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 4223 Lines: 124 In November of 2005 Oleg fixed a kernel crash with commit 7ed0175a462c ("[PATCH] Don't auto-reap traced children"). Oleg's patch was the fix for CVE-2005-3784 where one description says: The auto-reap of child processes in Linux kernel 2.6 before 2.6.15 includes processes with ptrace attached, which leads to a dangling ptrace reference and allows local users to cause a denial of service (crash) and gain root privileges. Not reaping the zombies resulted in zombies on the ptrace list when threads that ignored them exited. Resulting in Roland authoring 666f164f4fbf ("fix dangling zombie when new parent ignores children"). Which winds up auto-waiting for those zombies not when the tasks exit and become zombies but when the ptracer exits. As the kernel is already auto-waiting zombies for ptraced children rewrite the code to use the same code paths for auto-waiting as we use for all other children. This is a user visible change so something might care but as auto-wait at exit semantics are not documented anywhere, are in direct violation of what SIG_IGN and SA_NOCLDWAIT are documented by posix to do, and added to avoid a kernel crash, I don't expect there will be problems. Fixes: 7ed0175a462c ("[PATCH] Don't auto-reap traced children") Signed-off-by: "Eric W. Biederman" --- kernel/exit.c | 10 +++++++--- kernel/ptrace.c | 23 +---------------------- kernel/signal.c | 2 +- 3 files changed, 9 insertions(+), 26 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 2f01b75e3b2e..eaea41c8e646 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -638,7 +638,7 @@ static void forget_original_parent(struct task_struct *father, */ static void exit_notify(struct task_struct *tsk, int group_dead) { - int state = EXIT_DEAD; + int state; struct task_struct *p, *n; LIST_HEAD(dead); @@ -648,6 +648,8 @@ static void exit_notify(struct task_struct *tsk, int group_dead) if (group_dead) kill_orphaned_pgrp(tsk->group_leader, NULL); +renotify: + state = EXIT_DEAD; if (thread_group_leader(tsk) && !ptrace_reparented(tsk)) { state = EXIT_ZOMBIE; if (thread_group_empty(tsk) && @@ -656,8 +658,10 @@ static void exit_notify(struct task_struct *tsk, int group_dead) } else if (unlikely(tsk->ptrace)) { state = EXIT_TRACEE; - if (do_notify_parent(tsk, SIGCHLD)) - state = EXIT_DEAD; + if (do_notify_parent(tsk, SIGCHLD)) { + __ptrace_unlink(tsk); + goto renotify; + } } tsk->exit_state = state; diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 003567a615f9..c52cbbcbe258 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -468,19 +468,6 @@ static int ptrace_traceme(void) } /* - * Called with irqs disabled, returns true if childs should reap themselves. - */ -static int ignoring_children(struct sighand_struct *sigh) -{ - int ret; - spin_lock(&sigh->siglock); - ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) || - (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT); - spin_unlock(&sigh->siglock); - return ret; -} - -/* * Called with tasklist_lock held for writing. * Unlink a traced task, and clean it up if it was a traced zombie. * Return true if it needs to be reaped with release_task(). @@ -501,15 +488,7 @@ static bool __exit_ptrace(struct task_struct *tracer, struct task_struct *p) __ptrace_unlink(p); - if (state == EXIT_ZOMBIE) { - /* Honor the parents request to autoreap children */ - if (thread_group_empty(p) && - ignoring_children(tracer->sighand)) { - state = EXIT_DEAD; - __wake_up_parent(p, tracer); - } - } - else if (state == EXIT_TRACEE) { + if (state == EXIT_TRACEE) { state = EXIT_DEAD; if (thread_group_leader(p)) { state = EXIT_ZOMBIE; diff --git a/kernel/signal.c b/kernel/signal.c index 627b482fa3f8..30d652f86964 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1645,7 +1645,7 @@ bool do_notify_parent(struct task_struct *tsk, int sig) psig = tsk->parent->sighand; spin_lock_irqsave(&psig->siglock, flags); - if (!tsk->ptrace && sig == SIGCHLD && + if (sig == SIGCHLD && (psig->action[SIGCHLD-1].sa.sa_handler == SIG_IGN || (psig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT))) { /* -- 2.10.1