From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752000AbdFFTOv (ORCPT ); Tue, 6 Jun 2017 15:14:51 -0400 Received: from out02.mta.xmission.com ([166.70.13.232]:51918 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751561AbdFFTOo (ORCPT ); Tue, 6 Jun 2017 15:14:44 -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:23 -0500 Message-Id: <20170606190338.28347-11-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=1dIJu4-0006wd-LM;;;mid=<20170606190338.28347-11-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=97.121.81.159;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX183FREpQIuY3sjrgUuaj1Lg718RO7ozNqw= 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.7 XMSubLong Long Subject * 1.5 XMNoVowels Alpha-numberic number with no vowels * 0.0 TVD_RCVD_IP Message was received from an IP address * 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 * [sa04 1397; Body=1 Fuz1=1 Fuz2=1] * 0.0 T_TooManySym_01 4+ unique symbols in subject X-Spam-DCC: XMission; sa04 1397; Body=1 Fuz1=1 Fuz2=1 X-Spam-Combo: **;linux-kernel@vger.kernel.org X-Spam-Relay-Country: X-Spam-Timing: total 5539 ms - load_scoreonly_sql: 0.03 (0.0%), signal_user_changed: 2.2 (0.0%), b_tie_ro: 1.45 (0.0%), parse: 0.79 (0.0%), extract_message_metadata: 10 (0.2%), get_uri_detail_list: 1.81 (0.0%), tests_pri_-1000: 6 (0.1%), tests_pri_-950: 1.12 (0.0%), tests_pri_-900: 0.95 (0.0%), tests_pri_-400: 25 (0.5%), check_bayes: 24 (0.4%), b_tokenize: 8 (0.1%), b_tok_get_all: 10 (0.2%), b_comp_prob: 1.97 (0.0%), b_tok_touch_all: 2.9 (0.1%), b_finish: 0.52 (0.0%), tests_pri_0: 186 (3.4%), check_dkim_signature: 0.49 (0.0%), check_dkim_adsp: 2.4 (0.0%), tests_pri_500: 5304 (95.8%), poll_dns_idle: 5296 (95.6%), rewrite_mail: 0.00 (0.0%) Subject: [PATCH 11/26] wait: Properly implement __WCLONE handling in the presence of exec and ptrace 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 Rewrite the condition for what contitues a clone child. AKA a child that reports to it's parent using something other than SIGCHLD. If the parent has called exec since the child has started that child will alwasy report to it's parent with SIGCHLD. If the parent is only ptracing the child the child will always report to the parent with SIGCHLD. This implements the documented semantics and subsumes the fix Oleg made in 4.7 to make __WCLONE unnecessary when ptracing a child. It was just a bug in the check for __WCLONE support that made that necessary the ``semantic'' change necessary. Around v2.3.23 notify_parent was fixed to send SIGCHLD if the parent had exec'd. Fixing half a bug but wait was not fixed to see children in that case. Not handling either the ptrace or the parent exec case appears to go all of the way back to 1.0. Fixes: bf959931ddb8 ("wait/ptrace: assume __WALL if the child is traced") Fixes: v1.0 Fixes: v2.3.23 Signed-off-by: "Eric W. Biederman" --- kernel/exit.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index 625e57f1bb5c..306e526f4c5e 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -950,31 +950,26 @@ static int eligible_pid(struct wait_opts *wo, struct task_struct *p) task_pid_type(p, wo->wo_type) == wo->wo_pid; } -static int -eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p) +static int eligible_child(struct wait_opts *wo, struct task_struct *p) { if (!eligible_pid(wo, p)) return 0; /* - * Wait for all children (clone and not) if __WALL is set or - * if it is traced by us. + * Wait for all children (clone and not) if __WALL is set. */ - if (ptrace || (wo->wo_flags & __WALL)) + if (wo->wo_flags & __WALL) return 1; /* - * Otherwise, wait for clone children *only* if __WCLONE is set; - * otherwise, wait for non-clone children *only*. - * - * Note: a "clone" child here is one that reports to its parent - * using a signal other than SIGCHLD, or a non-leader thread which - * we can only see if it is traced by us. + * Otherwise wait for either children that report to their + * parent via SIGCHLD (when __WCLONE is not set) or use + * another signal (when __WCLONE is set). */ - if ((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE)) - return 0; - - return 1; + return (((p->exit_signal == SIGCHLD) || + (p->parent_exec_id == p->real_parent->self_exec_id)) + && thread_group_leader(p) && !ptrace_reparented(p)) ^ + !!(wo->wo_flags & __WCLONE); } static int wait_noreap_copyout(struct wait_opts *wo, struct task_struct *p, @@ -1343,7 +1338,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace, if (unlikely(exit_state == EXIT_DEAD)) return 0; - ret = eligible_child(wo, ptrace, p); + ret = eligible_child(wo, p); if (!ret) return ret; -- 2.10.1