From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8D78C433EF for ; Mon, 3 Jan 2022 21:33:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229954AbiACVde (ORCPT ); Mon, 3 Jan 2022 16:33:34 -0500 Received: from out02.mta.xmission.com ([166.70.13.232]:53420 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229921AbiACVdc (ORCPT ); Mon, 3 Jan 2022 16:33:32 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:58430) by out02.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxP-008tl7-M4; Mon, 03 Jan 2022 14:33:32 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxO-006zvm-DS; Mon, 03 Jan 2022 14:33:31 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:32:56 -0600 Message-Id: <20220103213312.9144-1-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4UxO-006zvm-DS;;;mid=<20220103213312.9144-1-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX181zeBt+KXrILoUBQNgwCvexzDgCTLCLYo= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 01/17] exit: Remove profile_task_exit & profile_munmap X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" When I say remove I mean remove. All profile_task_exit and profile_munmap do is call a blocking notifier chain. The helpers profile_task_register and profile_task_unregister are not called anywhere in the tree. Which means this is all dead code. So remove the dead code and make it easier to read do_exit. Signed-off-by: "Eric W. Biederman" Reviewed-by: Christoph Hellwig Suggested-by: Al Viro --- include/linux/profile.h | 26 --------------------- kernel/exit.c | 1 - kernel/profile.c | 50 ----------------------------------------- mm/mmap.c | 1 - 4 files changed, 78 deletions(-) diff --git a/include/linux/profile.h b/include/linux/profile.h index fd18ca96f557..f7eb2b57d890 100644 --- a/include/linux/profile.h +++ b/include/linux/profile.h @@ -31,11 +31,6 @@ static inline int create_proc_profile(void) } #endif =20 -enum profile_type { - PROFILE_TASK_EXIT, - PROFILE_MUNMAP -}; - #ifdef CONFIG_PROFILING =20 extern int prof_on __read_mostly; @@ -66,23 +61,14 @@ static inline void profile_hit(int type, void *ip) struct task_struct; struct mm_struct; =20 -/* task is in do_exit() */ -void profile_task_exit(struct task_struct * task); - /* task is dead, free task struct ? Returns 1 if * the task was taken, 0 if the task should be freed. */ int profile_handoff_task(struct task_struct * task); =20 -/* sys_munmap */ -void profile_munmap(unsigned long addr); - int task_handoff_register(struct notifier_block * n); int task_handoff_unregister(struct notifier_block * n); =20 -int profile_event_register(enum profile_type, struct notifier_block * n); -int profile_event_unregister(enum profile_type, struct notifier_block * n); - #else =20 #define prof_on 0 @@ -117,19 +103,7 @@ static inline int task_handoff_unregister(struct notif= ier_block * n) return -ENOSYS; } =20 -static inline int profile_event_register(enum profile_type t, struct notif= ier_block * n) -{ - return -ENOSYS; -} - -static inline int profile_event_unregister(enum profile_type t, struct not= ifier_block * n) -{ - return -ENOSYS; -} - -#define profile_task_exit(a) do { } while (0) #define profile_handoff_task(a) (0) -#define profile_munmap(a) do { } while (0) =20 #endif /* CONFIG_PROFILING */ =20 diff --git a/kernel/exit.c b/kernel/exit.c index e7104f803be0..b5c35b520fda 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -737,7 +737,6 @@ void __noreturn do_exit(long code) =20 WARN_ON(blk_needs_flush_plug(tsk)); =20 - profile_task_exit(tsk); kcov_task_exit(tsk); =20 coredump_task_exit(tsk); diff --git a/kernel/profile.c b/kernel/profile.c index eb9c7f0f5ac5..9355cc934a96 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -135,14 +135,7 @@ int __ref profile_init(void) =20 /* Profile event notifications */ =20 -static BLOCKING_NOTIFIER_HEAD(task_exit_notifier); static ATOMIC_NOTIFIER_HEAD(task_free_notifier); -static BLOCKING_NOTIFIER_HEAD(munmap_notifier); - -void profile_task_exit(struct task_struct *task) -{ - blocking_notifier_call_chain(&task_exit_notifier, 0, task); -} =20 int profile_handoff_task(struct task_struct *task) { @@ -151,11 +144,6 @@ int profile_handoff_task(struct task_struct *task) return (ret =3D=3D NOTIFY_OK) ? 1 : 0; } =20 -void profile_munmap(unsigned long addr) -{ - blocking_notifier_call_chain(&munmap_notifier, 0, (void *)addr); -} - int task_handoff_register(struct notifier_block *n) { return atomic_notifier_chain_register(&task_free_notifier, n); @@ -168,44 +156,6 @@ int task_handoff_unregister(struct notifier_block *n) } EXPORT_SYMBOL_GPL(task_handoff_unregister); =20 -int profile_event_register(enum profile_type type, struct notifier_block *= n) -{ - int err =3D -EINVAL; - - switch (type) { - case PROFILE_TASK_EXIT: - err =3D blocking_notifier_chain_register( - &task_exit_notifier, n); - break; - case PROFILE_MUNMAP: - err =3D blocking_notifier_chain_register( - &munmap_notifier, n); - break; - } - - return err; -} -EXPORT_SYMBOL_GPL(profile_event_register); - -int profile_event_unregister(enum profile_type type, struct notifier_block= *n) -{ - int err =3D -EINVAL; - - switch (type) { - case PROFILE_TASK_EXIT: - err =3D blocking_notifier_chain_unregister( - &task_exit_notifier, n); - break; - case PROFILE_MUNMAP: - err =3D blocking_notifier_chain_unregister( - &munmap_notifier, n); - break; - } - - return err; -} -EXPORT_SYMBOL_GPL(profile_event_unregister); - #if defined(CONFIG_SMP) && defined(CONFIG_PROC_FS) /* * Each cpu has a pair of open-addressed hashtables for pending diff --git a/mm/mmap.c b/mm/mmap.c index bfb0ea164a90..70318c2a47c3 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -2928,7 +2928,6 @@ EXPORT_SYMBOL(vm_munmap); SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) { addr =3D untagged_addr(addr); - profile_munmap(addr); return __vm_munmap(addr, len, true); } =20 --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CD979C43217 for ; Mon, 3 Jan 2022 21:33:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229979AbiACVdg (ORCPT ); Mon, 3 Jan 2022 16:33:36 -0500 Received: from out02.mta.xmission.com ([166.70.13.232]:53438 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229945AbiACVde (ORCPT ); Mon, 3 Jan 2022 16:33:34 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:58468) by out02.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxR-008tlQ-S4; Mon, 03 Jan 2022 14:33:33 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxQ-006zvm-PT; Mon, 03 Jan 2022 14:33:33 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:32:57 -0600 Message-Id: <20220103213312.9144-2-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4UxQ-006zvm-PT;;;mid=<20220103213312.9144-2-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX18ByO9TYSZ0MQyaKTM4mgHM9rHBx1s2UCg= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 02/17] exit: Coredumps reach do_group_exit X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The comment about coredumps not reaching do_group_exit and the corresponding BUG_ON are bogus. What happens and has happened for years is that get_signal calls do_coredump (which sets SIGNAL_GROUP_EXIT and group_exit_code) and then do_group_exit passing the signal number. Then do_group_exit ignores the exit_code it is passed and uses signal->group_exit_code from the coredump. The comment and BUG_ON were correct when they were added during the 2.5 development cycle, but became obsolete and incorrect when get_signal was changed to fall through to do_group_exit after do_coredump in 2.6.10-rc2. So remove the stale comment and BUG_ON Fixes: 63bd6144f191 ("[PATCH] Invalid BUG_ONs in signal.c") History-Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.= git Signed-off-by: "Eric W. Biederman" --- kernel/exit.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/exit.c b/kernel/exit.c index b5c35b520fda..34c43037450f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -904,8 +904,6 @@ do_group_exit(int exit_code) { struct signal_struct *sig =3D current->signal; =20 - BUG_ON(exit_code & 0x80); /* core dumps don't get here */ - if (sig->flags & SIGNAL_GROUP_EXIT) exit_code =3D sig->group_exit_code; else if (sig->group_exec_task) --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 179FCC433EF for ; Mon, 3 Jan 2022 21:33:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230009AbiACVdj (ORCPT ); Mon, 3 Jan 2022 16:33:39 -0500 Received: from out01.mta.xmission.com ([166.70.13.231]:55632 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229945AbiACVdh (ORCPT ); Mon, 3 Jan 2022 16:33:37 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:53662) by out01.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxU-008w9q-F0; Mon, 03 Jan 2022 14:33:36 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxS-006zvm-W0; Mon, 03 Jan 2022 14:33:36 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:32:58 -0600 Message-Id: <20220103213312.9144-3-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4UxS-006zvm-W0;;;mid=<20220103213312.9144-3-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX196ABXzRphm6Epu6ILDYOaOLYsB0yzq64Y= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 03/17] exit: Fix the exit_code for wait_task_zombie X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The function wait_task_zombie is defined to always returns the process not thread exit status. Unfortunately when process group exit support was added to wait_task_zombie the WNOWAIT case was overlooked. Usually tsk->exit_code and tsk->signal->group_exit_code will be in sync so fixing this is bug probably has no effect in practice. But fix it anyway so that people aren't scratching their heads about why the two code paths are different. History-Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.= git Fixes: 2c66151cbc2c ("[PATCH] sys_exit() threading improvements, BK-curr") Signed-off-by: "Eric W. Biederman" --- kernel/exit.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/exit.c b/kernel/exit.c index 34c43037450f..7121db37c411 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1011,7 +1011,8 @@ static int wait_task_zombie(struct wait_opts *wo, str= uct task_struct *p) return 0; =20 if (unlikely(wo->wo_flags & WNOWAIT)) { - status =3D p->exit_code; + status =3D (p->signal->flags & SIGNAL_GROUP_EXIT) + ? p->signal->group_exit_code : p->exit_code; get_task_struct(p); read_unlock(&tasklist_lock); sched_annotate_sleep(); --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 21732C4332F for ; Mon, 3 Jan 2022 21:33:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230037AbiACVdl (ORCPT ); Mon, 3 Jan 2022 16:33:41 -0500 Received: from out01.mta.xmission.com ([166.70.13.231]:55652 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229996AbiACVdj (ORCPT ); Mon, 3 Jan 2022 16:33:39 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:53720) by out01.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxW-008wAP-Eq; Mon, 03 Jan 2022 14:33:38 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxV-006zvm-HX; Mon, 03 Jan 2022 14:33:38 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:32:59 -0600 Message-Id: <20220103213312.9144-4-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4UxV-006zvm-HX;;;mid=<20220103213312.9144-4-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX19GwdHKdiijovtG0K+pecNRJriBL3YbcO0= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 04/17] exit: Use the correct exit_code in /proc//stat X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Since do_proc_statt was modified to return process wide values instead of per task values the exit_code calculation has never been updated. Update it now to return the process wide exit_code when it is requested and available. History-Tree: https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.= git Fixes: bf719d26a5c1 ("[PATCH] distinct tgid/tid CPU usage") Signed-off-by: "Eric W. Biederman" --- fs/proc/array.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/proc/array.c b/fs/proc/array.c index ff869a66b34e..43a7abde9e42 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -468,6 +468,7 @@ static int do_task_stat(struct seq_file *m, struct pid_= namespace *ns, u64 cgtime, gtime; unsigned long rsslim =3D 0; unsigned long flags; + int exit_code =3D task->exit_code; =20 state =3D *get_task_state(task); vsize =3D eip =3D esp =3D 0; @@ -531,6 +532,9 @@ static int do_task_stat(struct seq_file *m, struct pid_= namespace *ns, maj_flt +=3D sig->maj_flt; thread_group_cputime_adjusted(task, &utime, &stime); gtime +=3D sig->gtime; + + if (sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_STOP_STOPPED)) + exit_code =3D sig->group_exit_code; } =20 sid =3D task_session_nr_ns(task, ns); @@ -630,7 +634,7 @@ static int do_task_stat(struct seq_file *m, struct pid_= namespace *ns, seq_puts(m, " 0 0 0 0 0 0 0"); =20 if (permitted) - seq_put_decimal_ll(m, " ", task->exit_code); + seq_put_decimal_ll(m, " ", exit_code); else seq_puts(m, " 0"); =20 --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9D853C433F5 for ; Mon, 3 Jan 2022 21:33:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230043AbiACVdu (ORCPT ); Mon, 3 Jan 2022 16:33:50 -0500 Received: from out03.mta.xmission.com ([166.70.13.233]:45860 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229996AbiACVdm (ORCPT ); Mon, 3 Jan 2022 16:33:42 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:56344) by out03.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxY-00ET0Q-W5; Mon, 03 Jan 2022 14:33:41 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4UxX-006zvm-MV; Mon, 03 Jan 2022 14:33:40 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" , Balbir Singh Date: Mon, 3 Jan 2022 15:33:00 -0600 Message-Id: <20220103213312.9144-5-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4UxX-006zvm-MV;;;mid=<20220103213312.9144-5-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1+CRWzVLNnenVGaaRiHLlq9SOWL8zsSG+U= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 05/17] taskstats: Cleanup the use of task->exit_code X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In the function bacct_add_task the code reading task->exit_code was introduced in commit f3cef7a99469 ("[PATCH] csa: basic accounting over taskstats"), and it is not entirely clear what the taskstats interface is trying to return as only returning the exit_code of the first task in a process doesn't make a lot of sense. As best as I can figure the intent is to return task->exit_code after a task exits. The field is returned with per task fields, so the exit_code of the entire process is not wanted. Only the value of the first task is returned so this is not a useful way to get the per task ptrace stop code. The ordinary case of returning this value is returning after a task exits, which also precludes use for getting a ptrace value. It is common to for the first task of a process to also be the last task of a process so this field may have done something reasonable by accident in testing. Make ac_exitcode a reliable per task value by always returning it for every exited task. Setting ac_exitcode in a sensible mannter makes it possible to continue to provide this value going forward. Cc: Balbir Singh Fixes: f3cef7a99469 ("[PATCH] csa: basic accounting over taskstats") Signed-off-by: "Eric W. Biederman" --- kernel/tsacct.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/kernel/tsacct.c b/kernel/tsacct.c index f00de83d0246..1d261fbe367b 100644 --- a/kernel/tsacct.c +++ b/kernel/tsacct.c @@ -38,11 +38,10 @@ void bacct_add_tsk(struct user_namespace *user_ns, stats->ac_btime =3D clamp_t(time64_t, btime, 0, U32_MAX); stats->ac_btime64 =3D btime; =20 - if (thread_group_leader(tsk)) { + if (tsk->flags & PF_EXITING) stats->ac_exitcode =3D tsk->exit_code; - if (tsk->flags & PF_FORKNOEXEC) - stats->ac_flag |=3D AFORK; - } + if (thread_group_leader(tsk) && (tsk->flags & PF_FORKNOEXEC)) + stats->ac_flag |=3D AFORK; if (tsk->flags & PF_SUPERPRIV) stats->ac_flag |=3D ASU; if (tsk->flags & PF_DUMPCORE) --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C78D3C433F5 for ; Mon, 3 Jan 2022 21:33:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230089AbiACVds (ORCPT ); Mon, 3 Jan 2022 16:33:48 -0500 Received: from out01.mta.xmission.com ([166.70.13.231]:55670 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230071AbiACVdo (ORCPT ); Mon, 3 Jan 2022 16:33:44 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:53832) by out01.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxb-008wAq-Hp; Mon, 03 Jan 2022 14:33:43 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxa-006zvm-2s; Mon, 03 Jan 2022 14:33:43 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:01 -0600 Message-Id: <20220103213312.9144-6-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxa-006zvm-2s;;;mid=<20220103213312.9144-6-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1/AooRDxSBy7IO0iwcfMe3FQDLmY0Bv32g= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 06/17] ptrace: Remove second setting of PT_SEIZED in ptrace_attach X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The code is totally redundant remove it. Signed-off-by: "Eric W. Biederman" --- kernel/ptrace.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index f8589bf8d7dc..eea265082e97 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -419,8 +419,6 @@ static int ptrace_attach(struct task_struct *task, long= request, if (task->ptrace) goto unlock_tasklist; =20 - if (seize) - flags |=3D PT_SEIZED; task->ptrace =3D flags; =20 ptrace_link(task, current); --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25DB1C433EF for ; Mon, 3 Jan 2022 21:33:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230142AbiACVdw (ORCPT ); Mon, 3 Jan 2022 16:33:52 -0500 Received: from out03.mta.xmission.com ([166.70.13.233]:45880 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230093AbiACVdq (ORCPT ); Mon, 3 Jan 2022 16:33:46 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:56440) by out03.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxd-00ET0p-J6; Mon, 03 Jan 2022 14:33:45 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxc-006zvm-Lm; Mon, 03 Jan 2022 14:33:45 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:02 -0600 Message-Id: <20220103213312.9144-7-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxc-006zvm-Lm;;;mid=<20220103213312.9144-7-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX18jgqYxlIKA82Fl1bV6Gg+kb1TtzswAvHE= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 07/17] ptrace: Remove unused regs argument from ptrace_report_syscall X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Signed-off-by: "Eric W. Biederman" --- include/linux/tracehook.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 2564b7434b4d..88c007ab5ebc 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -54,8 +54,7 @@ struct linux_binprm; /* * ptrace report for syscall entry and exit looks identical. */ -static inline int ptrace_report_syscall(struct pt_regs *regs, - unsigned long message) +static inline int ptrace_report_syscall(unsigned long message) { int ptrace =3D current->ptrace; =20 @@ -102,7 +101,7 @@ static inline int ptrace_report_syscall(struct pt_regs = *regs, static inline __must_check int tracehook_report_syscall_entry( struct pt_regs *regs) { - return ptrace_report_syscall(regs, PTRACE_EVENTMSG_SYSCALL_ENTRY); + return ptrace_report_syscall(PTRACE_EVENTMSG_SYSCALL_ENTRY); } =20 /** @@ -127,7 +126,7 @@ static inline void tracehook_report_syscall_exit(struct= pt_regs *regs, int step) if (step) user_single_step_report(regs); else - ptrace_report_syscall(regs, PTRACE_EVENTMSG_SYSCALL_EXIT); + ptrace_report_syscall(PTRACE_EVENTMSG_SYSCALL_EXIT); } =20 /** --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F5F1C433FE for ; Mon, 3 Jan 2022 21:33:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230091AbiACVd5 (ORCPT ); Mon, 3 Jan 2022 16:33:57 -0500 Received: from out03.mta.xmission.com ([166.70.13.233]:45890 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230013AbiACVdt (ORCPT ); Mon, 3 Jan 2022 16:33:49 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:56496) by out03.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxf-00ET10-VJ; Mon, 03 Jan 2022 14:33:48 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxe-006zvm-Oo; Mon, 03 Jan 2022 14:33:47 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" , Geert Uytterhoeven Date: Mon, 3 Jan 2022 15:33:03 -0600 Message-Id: <20220103213312.9144-8-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxe-006zvm-Oo;;;mid=<20220103213312.9144-8-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX19v1FHwGXBXGWLQ9gxNwRHnNBkfOqEsAZQ= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 08/17] ptrace/m68k: Stop open coding ptrace_report_syscall X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The generic function ptrace_report_syscall does a little more than syscall_trace on m68k. The function ptrace_report_syscall stops early if PT_TRACED is not set, it sets ptrace_message, and returns the result of fatal_signal_pending. Setting ptrace_message to a passed in value of 0 is effectively not setting ptrace_message, making that additional work a noop. Returning the result of fatal_signal_pending and letting the caller ignore the result becomes a noop in this change. When a process is ptraced, the flag PT_PTRACED is always set in current->ptrace. Testing for PT_PTRACED in ptrace_report_syscall is just an optimization to fail early if the process is not ptraced. Later on in ptrace_notify, ptrace_stop will test current->ptrace under tasklist_lock and skip performing any work if the task is not ptraced. Cc: Geert Uytterhoeven Signed-off-by: "Eric W. Biederman" --- arch/m68k/kernel/ptrace.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index 94b3b274186d..aa3a0b8d07e9 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c @@ -273,17 +273,7 @@ long arch_ptrace(struct task_struct *child, long reque= st, =20 asmlinkage void syscall_trace(void) { - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code =3D 0; - } + ptrace_report_syscall(0); } =20 #if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU) --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A9F1CC433F5 for ; Mon, 3 Jan 2022 21:34:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230187AbiACVeA (ORCPT ); Mon, 3 Jan 2022 16:34:00 -0500 Received: from out02.mta.xmission.com ([166.70.13.232]:53460 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230146AbiACVdy (ORCPT ); Mon, 3 Jan 2022 16:33:54 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:58906) by out02.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxk-008tm1-Ss; Mon, 03 Jan 2022 14:33:52 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxh-006zvm-6k; Mon, 03 Jan 2022 14:33:52 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:04 -0600 Message-Id: <20220103213312.9144-9-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxh-006zvm-6k;;;mid=<20220103213312.9144-9-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1+y48VyZYQuysk3s96g6DwRz5UUcdOr+6o= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 09/17] ptrace: Move setting/clearing ptrace_message into ptrace_stop X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Today ptrace_message is easy to overlook as it not a core part of ptrace_stop. It has been overlooked so much that there are places that set ptrace_message and don't clear it, and places that never set it. So if you get an unlucky sequence of events the ptracer may be able to read a ptrace_message that does not apply to the current ptrace stop. Move setting of ptrace_message into ptrace_stop so that it always gets set before the stop, and always gets cleared after the stop. This prevents non-sense from being reported to userspace and makes ptrace_message more visible in the ptrace API so that kernel developers can see it. Signed-off-by: "Eric W. Biederman" --- include/linux/ptrace.h | 5 ++--- include/linux/tracehook.h | 6 ++---- kernel/signal.c | 19 +++++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 8aee2945ff08..06f27736c6f8 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -60,7 +60,7 @@ extern int ptrace_writedata(struct task_struct *tsk, char= __user *src, unsigned extern void ptrace_disable(struct task_struct *); extern int ptrace_request(struct task_struct *child, long request, unsigned long addr, unsigned long data); -extern void ptrace_notify(int exit_code); +extern void ptrace_notify(int exit_code, unsigned long message); extern void __ptrace_link(struct task_struct *child, struct task_struct *new_parent, const struct cred *ptracer_cred); @@ -155,8 +155,7 @@ static inline bool ptrace_event_enabled(struct task_str= uct *task, int event) static inline void ptrace_event(int event, unsigned long message) { if (unlikely(ptrace_event_enabled(current, event))) { - current->ptrace_message =3D message; - ptrace_notify((event << 8) | SIGTRAP); + ptrace_notify((event << 8) | SIGTRAP, message); } else if (event =3D=3D PTRACE_EVENT_EXEC) { /* legacy EXEC report via SIGTRAP */ if ((current->ptrace & (PT_PTRACED|PT_SEIZED)) =3D=3D PT_PTRACED) diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 88c007ab5ebc..5e60af8a11fc 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -61,8 +61,7 @@ static inline int ptrace_report_syscall(unsigned long mes= sage) if (!(ptrace & PT_PTRACED)) return 0; =20 - current->ptrace_message =3D message; - ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); + ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0), message); =20 /* * this isn't the same as continuing with a signal, but it will do @@ -74,7 +73,6 @@ static inline int ptrace_report_syscall(unsigned long mes= sage) current->exit_code =3D 0; } =20 - current->ptrace_message =3D 0; return fatal_signal_pending(current); } =20 @@ -143,7 +141,7 @@ static inline void tracehook_report_syscall_exit(struct= pt_regs *regs, int step) static inline void tracehook_signal_handler(int stepping) { if (stepping) - ptrace_notify(SIGTRAP); + ptrace_notify(SIGTRAP, 0); } =20 /** diff --git a/kernel/signal.c b/kernel/signal.c index 802acca0207b..75bb062d8534 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2197,7 +2197,8 @@ static void do_notify_parent_cldstop(struct task_stru= ct *tsk, * If we actually decide not to stop at all because the tracer * is gone, we keep current->exit_code unless clear_code. */ -static void ptrace_stop(int exit_code, int why, int clear_code, kernel_sig= info_t *info) +static void ptrace_stop(int exit_code, int why, int clear_code, + unsigned long message, kernel_siginfo_t *info) __releases(¤t->sighand->siglock) __acquires(¤t->sighand->siglock) { @@ -2243,6 +2244,7 @@ static void ptrace_stop(int exit_code, int why, int c= lear_code, kernel_siginfo_t */ smp_wmb(); =20 + current->ptrace_message =3D message; current->last_siginfo =3D info; current->exit_code =3D exit_code; =20 @@ -2321,6 +2323,7 @@ static void ptrace_stop(int exit_code, int why, int c= lear_code, kernel_siginfo_t */ spin_lock_irq(¤t->sighand->siglock); current->last_siginfo =3D NULL; + current->ptrace_message =3D 0; =20 /* LISTENING can be set only during STOP traps, clear it */ current->jobctl &=3D ~JOBCTL_LISTENING; @@ -2333,7 +2336,7 @@ static void ptrace_stop(int exit_code, int why, int c= lear_code, kernel_siginfo_t recalc_sigpending_tsk(current); } =20 -static void ptrace_do_notify(int signr, int exit_code, int why) +static void ptrace_do_notify(int signr, int exit_code, int why, unsigned l= ong message) { kernel_siginfo_t info; =20 @@ -2344,17 +2347,17 @@ static void ptrace_do_notify(int signr, int exit_co= de, int why) info.si_uid =3D from_kuid_munged(current_user_ns(), current_uid()); =20 /* Let the debugger run. */ - ptrace_stop(exit_code, why, 1, &info); + ptrace_stop(exit_code, why, 1, message, &info); } =20 -void ptrace_notify(int exit_code) +void ptrace_notify(int exit_code, unsigned long message) { BUG_ON((exit_code & (0x7f | ~0xffff)) !=3D SIGTRAP); if (unlikely(current->task_works)) task_work_run(); =20 spin_lock_irq(¤t->sighand->siglock); - ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED); + ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED, message); spin_unlock_irq(¤t->sighand->siglock); } =20 @@ -2510,10 +2513,10 @@ static void do_jobctl_trap(void) signr =3D SIGTRAP; WARN_ON_ONCE(!signr); ptrace_do_notify(signr, signr | (PTRACE_EVENT_STOP << 8), - CLD_STOPPED); + CLD_STOPPED, 0); } else { WARN_ON_ONCE(!signr); - ptrace_stop(signr, CLD_STOPPED, 0, NULL); + ptrace_stop(signr, CLD_STOPPED, 0, 0, NULL); current->exit_code =3D 0; } } @@ -2567,7 +2570,7 @@ static int ptrace_signal(int signr, kernel_siginfo_t = *info, enum pid_type type) * comment in dequeue_signal(). */ current->jobctl |=3D JOBCTL_STOP_DEQUEUED; - ptrace_stop(signr, CLD_TRAPPED, 0, info); + ptrace_stop(signr, CLD_TRAPPED, 0, 0, info); =20 /* We're back. Did the debugger cancel the sig? */ signr =3D current->exit_code; --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC97AC433EF for ; Mon, 3 Jan 2022 21:34:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230264AbiACVeF (ORCPT ); Mon, 3 Jan 2022 16:34:05 -0500 Received: from out03.mta.xmission.com ([166.70.13.233]:45908 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230163AbiACVd4 (ORCPT ); Mon, 3 Jan 2022 16:33:56 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:56668) by out03.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxn-00ET1a-AZ; Mon, 03 Jan 2022 14:33:55 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxl-006zvm-W6; Mon, 03 Jan 2022 14:33:54 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:05 -0600 Message-Id: <20220103213312.9144-10-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxl-006zvm-W6;;;mid=<20220103213312.9144-10-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1/CoLSF+5aKtgflxHOhPtbt/lqg7uqig4s= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 10/17] ptrace: Return the signal to continue with from ptrace_stop X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The signal a task should continue with after a ptrace stop is inconsistently read, cleared, and sent. Solve this by reading and clearing the signal to be sent in ptrace_stop. In an ideal world everything except ptrace_signal would share a common implementation of continuing with the signal, so ptracers could count on the signal they ask to continue with actually being delivered. For now retain bug compatibility and just return with the signal number the ptracer requested the code continue with. Signed-off-by: "Eric W. Biederman" --- include/linux/ptrace.h | 2 +- include/linux/tracehook.h | 10 +++++----- kernel/signal.c | 31 ++++++++++++++++++------------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 06f27736c6f8..323c9950e705 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -60,7 +60,7 @@ extern int ptrace_writedata(struct task_struct *tsk, char= __user *src, unsigned extern void ptrace_disable(struct task_struct *); extern int ptrace_request(struct task_struct *child, long request, unsigned long addr, unsigned long data); -extern void ptrace_notify(int exit_code, unsigned long message); +extern int ptrace_notify(int exit_code, unsigned long message); extern void __ptrace_link(struct task_struct *child, struct task_struct *new_parent, const struct cred *ptracer_cred); diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 5e60af8a11fc..2fd0bfe866c0 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -57,21 +57,21 @@ struct linux_binprm; static inline int ptrace_report_syscall(unsigned long message) { int ptrace =3D current->ptrace; + int signr; =20 if (!(ptrace & PT_PTRACED)) return 0; =20 - ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0), message); + signr =3D ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0), + message); =20 /* * this isn't the same as continuing with a signal, but it will do * for normal use. strace only continues with a signal if the * stopping signal is not SIGTRAP. -brl */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code =3D 0; - } + if (signr) + send_sig(signr, current, 1); =20 return fatal_signal_pending(current); } diff --git a/kernel/signal.c b/kernel/signal.c index 75bb062d8534..9903ff12e581 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2194,15 +2194,17 @@ static void do_notify_parent_cldstop(struct task_st= ruct *tsk, * That makes it a way to test a stopped process for * being ptrace-stopped vs being job-control-stopped. * - * If we actually decide not to stop at all because the tracer - * is gone, we keep current->exit_code unless clear_code. + * Returns the signal the ptracer requested the code resume + * with. If the code did not stop because the tracer is gone, + * the stop signal remains unchanged unless clear_code. */ -static void ptrace_stop(int exit_code, int why, int clear_code, +static int ptrace_stop(int exit_code, int why, int clear_code, unsigned long message, kernel_siginfo_t *info) __releases(¤t->sighand->siglock) __acquires(¤t->sighand->siglock) { bool gstop_done =3D false; + bool read_code =3D true; =20 if (arch_ptrace_stop_needed()) { /* @@ -2311,8 +2313,9 @@ static void ptrace_stop(int exit_code, int why, int c= lear_code, =20 /* tasklist protects us from ptrace_freeze_traced() */ __set_current_state(TASK_RUNNING); + read_code =3D false; if (clear_code) - current->exit_code =3D 0; + exit_code =3D 0; read_unlock(&tasklist_lock); } =20 @@ -2322,8 +2325,10 @@ static void ptrace_stop(int exit_code, int why, int = clear_code, * any signal-sending on another CPU that wants to examine it. */ spin_lock_irq(¤t->sighand->siglock); + if (read_code) exit_code =3D current->exit_code; current->last_siginfo =3D NULL; current->ptrace_message =3D 0; + current->exit_code =3D 0; =20 /* LISTENING can be set only during STOP traps, clear it */ current->jobctl &=3D ~JOBCTL_LISTENING; @@ -2334,9 +2339,10 @@ static void ptrace_stop(int exit_code, int why, int = clear_code, * This sets TIF_SIGPENDING, but never clears it. */ recalc_sigpending_tsk(current); + return exit_code; } =20 -static void ptrace_do_notify(int signr, int exit_code, int why, unsigned l= ong message) +static int ptrace_do_notify(int signr, int exit_code, int why, unsigned lo= ng message) { kernel_siginfo_t info; =20 @@ -2347,18 +2353,21 @@ static void ptrace_do_notify(int signr, int exit_co= de, int why, unsigned long me info.si_uid =3D from_kuid_munged(current_user_ns(), current_uid()); =20 /* Let the debugger run. */ - ptrace_stop(exit_code, why, 1, message, &info); + return ptrace_stop(exit_code, why, 1, message, &info); } =20 -void ptrace_notify(int exit_code, unsigned long message) +int ptrace_notify(int exit_code, unsigned long message) { + int signr; + BUG_ON((exit_code & (0x7f | ~0xffff)) !=3D SIGTRAP); if (unlikely(current->task_works)) task_work_run(); =20 spin_lock_irq(¤t->sighand->siglock); - ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED, message); + signr =3D ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED, message); spin_unlock_irq(¤t->sighand->siglock); + return signr; } =20 /** @@ -2517,7 +2526,6 @@ static void do_jobctl_trap(void) } else { WARN_ON_ONCE(!signr); ptrace_stop(signr, CLD_STOPPED, 0, 0, NULL); - current->exit_code =3D 0; } } =20 @@ -2570,15 +2578,12 @@ static int ptrace_signal(int signr, kernel_siginfo_= t *info, enum pid_type type) * comment in dequeue_signal(). */ current->jobctl |=3D JOBCTL_STOP_DEQUEUED; - ptrace_stop(signr, CLD_TRAPPED, 0, 0, info); + signr =3D ptrace_stop(signr, CLD_TRAPPED, 0, 0, info); =20 /* We're back. Did the debugger cancel the sig? */ - signr =3D current->exit_code; if (signr =3D=3D 0) return signr; =20 - current->exit_code =3D 0; - /* * Update the siginfo structure if the signal has * changed. If the debugger wanted something --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 63074C433FE for ; Mon, 3 Jan 2022 21:34:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230077AbiACVeP (ORCPT ); Mon, 3 Jan 2022 16:34:15 -0500 Received: from out01.mta.xmission.com ([166.70.13.231]:55714 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230109AbiACVd6 (ORCPT ); Mon, 3 Jan 2022 16:33:58 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:54168) by out01.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxp-008wC2-R7; Mon, 03 Jan 2022 14:33:57 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxo-006zvm-Gp; Mon, 03 Jan 2022 14:33:57 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:06 -0600 Message-Id: <20220103213312.9144-11-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxo-006zvm-Gp;;;mid=<20220103213312.9144-11-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX190mElOvs4SYiKuQHnfeTivnEFRnZqD7i0= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 11/17] ptrace: Separate task->ptrace_code out from task->exit_code X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" A process can be marked for death by setting SIGNAL_GROUP_EXIT and group_exit_code, long before do_exit is called. Unfortunately because of PTRACE_EVENT_EXIT residing in do_exit this same tactic can not be used for task death. Correct this by adding a new task field task->ptrace_code that holds the code for ptrace stops. This allows task->exit_code to be set to the exit code long before the PTRACE_EVENT_EXIT ptrace stop. Signed-off-by: "Eric W. Biederman" --- fs/proc/array.c | 3 +++ include/linux/sched.h | 1 + kernel/exit.c | 2 +- kernel/ptrace.c | 12 ++++++------ kernel/signal.c | 18 +++++++++--------- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/fs/proc/array.c b/fs/proc/array.c index 43a7abde9e42..3042015c11ad 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -519,6 +519,9 @@ static int do_task_stat(struct seq_file *m, struct pid_= namespace *ns, cgtime =3D sig->cgtime; rsslim =3D READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur); =20 + if (task_is_traced(task) && !(task->jobctl & JOBCTL_LISTENING)) + exit_code =3D task->ptrace_code; + /* add up live thread stats at the group level */ if (whole) { struct task_struct *t =3D task; diff --git a/include/linux/sched.h b/include/linux/sched.h index 52f2fdffa3ab..c3d732bf7833 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1174,6 +1174,7 @@ struct task_struct { /* Ptrace state: */ unsigned long ptrace_message; kernel_siginfo_t *last_siginfo; + int ptrace_code; =20 struct task_io_accounting ioac; #ifdef CONFIG_PSI diff --git a/kernel/exit.c b/kernel/exit.c index 7121db37c411..aedefe5eb0eb 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -1134,7 +1134,7 @@ static int *task_stopped_code(struct task_struct *p, = bool ptrace) { if (ptrace) { if (task_is_traced(p) && !(p->jobctl & JOBCTL_LISTENING)) - return &p->exit_code; + return &p->ptrace_code; } else { if (p->signal->flags & SIGNAL_STOP_STOPPED) return &p->signal->group_exit_code; diff --git a/kernel/ptrace.c b/kernel/ptrace.c index eea265082e97..8bbd73ab9a34 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -172,7 +172,7 @@ void __ptrace_unlink(struct task_struct *child) =20 static bool looks_like_a_spurious_pid(struct task_struct *task) { - if (task->exit_code !=3D ((PTRACE_EVENT_EXEC << 8) | SIGTRAP)) + if (task->ptrace_code !=3D ((PTRACE_EVENT_EXEC << 8) | SIGTRAP)) return false; =20 if (task_pid_vnr(task) =3D=3D task->ptrace_message) @@ -573,7 +573,7 @@ static int ptrace_detach(struct task_struct *child, uns= igned int data) * tasklist_lock avoids the race with wait_task_stopped(), see * the comment in ptrace_resume(). */ - child->exit_code =3D data; + child->ptrace_code =3D data; __ptrace_detach(current, child); write_unlock_irq(&tasklist_lock); =20 @@ -863,11 +863,11 @@ static int ptrace_resume(struct task_struct *child, l= ong request, } =20 /* - * Change ->exit_code and ->state under siglock to avoid the race - * with wait_task_stopped() in between; a non-zero ->exit_code will + * Change ->ptrace_code and ->state under siglock to avoid the race + * with wait_task_stopped() in between; a non-zero ->ptrace_code will * wrongly look like another report from tracee. * - * Note that we need siglock even if ->exit_code =3D=3D data and/or this + * Note that we need siglock even if ->ptrace_code =3D=3D data and/or this * status was not reported yet, the new status must not be cleared by * wait_task_stopped() after resume. * @@ -878,7 +878,7 @@ static int ptrace_resume(struct task_struct *child, lon= g request, need_siglock =3D data && !thread_group_empty(current); if (need_siglock) spin_lock_irq(&child->sighand->siglock); - child->exit_code =3D data; + child->ptrace_code =3D data; wake_up_state(child, __TASK_TRACED); if (need_siglock) spin_unlock_irq(&child->sighand->siglock); diff --git a/kernel/signal.c b/kernel/signal.c index 9903ff12e581..fd3c404de8b6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2168,7 +2168,7 @@ static void do_notify_parent_cldstop(struct task_stru= ct *tsk, info.si_status =3D tsk->signal->group_exit_code & 0x7f; break; case CLD_TRAPPED: - info.si_status =3D tsk->exit_code & 0x7f; + info.si_status =3D tsk->ptrace_code & 0x7f; break; default: BUG(); @@ -2198,7 +2198,7 @@ static void do_notify_parent_cldstop(struct task_stru= ct *tsk, * with. If the code did not stop because the tracer is gone, * the stop signal remains unchanged unless clear_code. */ -static int ptrace_stop(int exit_code, int why, int clear_code, +static int ptrace_stop(int code, int why, int clear_code, unsigned long message, kernel_siginfo_t *info) __releases(¤t->sighand->siglock) __acquires(¤t->sighand->siglock) @@ -2248,7 +2248,7 @@ static int ptrace_stop(int exit_code, int why, int cl= ear_code, =20 current->ptrace_message =3D message; current->last_siginfo =3D info; - current->exit_code =3D exit_code; + current->ptrace_code =3D code; =20 /* * If @why is CLD_STOPPED, we're trapping to participate in a group @@ -2315,7 +2315,7 @@ static int ptrace_stop(int exit_code, int why, int cl= ear_code, __set_current_state(TASK_RUNNING); read_code =3D false; if (clear_code) - exit_code =3D 0; + code =3D 0; read_unlock(&tasklist_lock); } =20 @@ -2325,10 +2325,10 @@ static int ptrace_stop(int exit_code, int why, int = clear_code, * any signal-sending on another CPU that wants to examine it. */ spin_lock_irq(¤t->sighand->siglock); - if (read_code) exit_code =3D current->exit_code; + if (read_code) code =3D current->ptrace_code; current->last_siginfo =3D NULL; current->ptrace_message =3D 0; - current->exit_code =3D 0; + current->ptrace_code =3D 0; =20 /* LISTENING can be set only during STOP traps, clear it */ current->jobctl &=3D ~JOBCTL_LISTENING; @@ -2339,7 +2339,7 @@ static int ptrace_stop(int exit_code, int why, int cl= ear_code, * This sets TIF_SIGPENDING, but never clears it. */ recalc_sigpending_tsk(current); - return exit_code; + return code; } =20 static int ptrace_do_notify(int signr, int exit_code, int why, unsigned lo= ng message) @@ -2501,11 +2501,11 @@ static bool do_signal_stop(int signr) * * When PT_SEIZED, it's used for both group stop and explicit * SEIZE/INTERRUPT traps. Both generate PTRACE_EVENT_STOP trap with - * accompanying siginfo. If stopped, lower eight bits of exit_code contain + * accompanying siginfo. If stopped, lower eight bits of ptrace_code cont= ain * the stop signal; otherwise, %SIGTRAP. * * When !PT_SEIZED, it's used only for group stop trap with stop signal - * number as exit_code and no siginfo. + * number as ptrace_code and no siginfo. * * CONTEXT: * Must be called with @current->sighand->siglock held, which may be --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3A07EC43219 for ; Mon, 3 Jan 2022 21:34:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230228AbiACVeS (ORCPT ); Mon, 3 Jan 2022 16:34:18 -0500 Received: from out01.mta.xmission.com ([166.70.13.231]:55732 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230153AbiACVeA (ORCPT ); Mon, 3 Jan 2022 16:34:00 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:54216) by out01.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxr-008wCI-UK; Mon, 03 Jan 2022 14:33:59 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxq-006zvm-VO; Mon, 03 Jan 2022 14:33:59 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:07 -0600 Message-Id: <20220103213312.9144-12-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxq-006zvm-VO;;;mid=<20220103213312.9144-12-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX19dmJ8eKxvuQTy3KtHmk9FlXTI4tuhzGNw= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 12/17] signal: Compute the process exit_code in get_signal X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" In prepartion for moving the work of sys_exit and sys_group_exit into get_signal compute exit_code in get_signal, make PF_SIGNALED depend on the exit_code and pass the exit_code to do_group_exit. Anytime there is a group exit the exit_code may differ from the signal number. To match the historical precedent as best I can make the exit_code 0 during exec. (The exit_code field would not have been set but probably would have been left at a value of 0). Signed-off-by: "Eric W. Biederman" --- kernel/signal.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/kernel/signal.c b/kernel/signal.c index fd3c404de8b6..2a24cca00ca1 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2707,6 +2707,7 @@ bool get_signal(struct ksignal *ksig) for (;;) { struct k_sigaction *ka; enum pid_type type; + int exit_code; =20 /* Has this task already been marked for death? */ if ((signal->flags & SIGNAL_GROUP_EXIT) || @@ -2716,6 +2717,10 @@ bool get_signal(struct ksignal *ksig) trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO, &sighand->action[SIGKILL - 1]); recalc_sigpending(); + if (signal->flags & SIGNAL_GROUP_EXIT) + exit_code =3D signal->group_exit_code; + else + exit_code =3D 0; goto fatal; } =20 @@ -2837,15 +2842,17 @@ bool get_signal(struct ksignal *ksig) continue; } =20 + /* + * Anything else is fatal, maybe with a core dump. + */ + exit_code =3D signr; fatal: spin_unlock_irq(&sighand->siglock); if (unlikely(cgroup_task_frozen(current))) cgroup_leave_frozen(true); =20 - /* - * Anything else is fatal, maybe with a core dump. - */ - current->flags |=3D PF_SIGNALED; + if (exit_code & 0x7f) + current->flags |=3D PF_SIGNALED; =20 if (sig_kernel_coredump(signr)) { if (print_fatal_signals) @@ -2873,7 +2880,7 @@ bool get_signal(struct ksignal *ksig) /* * Death signals, no core dump. */ - do_group_exit(ksig->info.si_signo); + do_group_exit(exit_code); /* NOTREACHED */ } spin_unlock_irq(&sighand->siglock); --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6A962C433EF for ; Mon, 3 Jan 2022 21:34:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230245AbiACVeV (ORCPT ); Mon, 3 Jan 2022 16:34:21 -0500 Received: from out01.mta.xmission.com ([166.70.13.231]:55742 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230219AbiACVeC (ORCPT ); Mon, 3 Jan 2022 16:34:02 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:54298) by out01.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxu-008wCZ-5g; Mon, 03 Jan 2022 14:34:02 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxt-006zvm-1z; Mon, 03 Jan 2022 14:34:01 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:08 -0600 Message-Id: <20220103213312.9144-13-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxt-006zvm-1z;;;mid=<20220103213312.9144-13-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1/ve0A1nOdiKJFClkslmix271YQhosArc8= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 13/17] signal: Make individual tasks exiting a first class concept X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add a helper schedule_task_exit_locked that is equivalent to asynchronously calling exit(2) except for not having an exit code. This is a generalization of what happens in de_thread, zap_process, prepare_signal, complete_signal, and zap_other_threads when individual tasks are asked to shutdown. The various code paths optimize away the setting sigaddset and signal_wake_up based on different conditions. Neither sigaddset nor signal_wake_up are needed if the task has already started running do_exit. So skip the work if PF_POSTCOREDUMP is set. Which is the earliest any of the original hand rolled implementations used. Update get_signal to detect either signal group exit or a single task exit by testing for __fatal_signal_pending. This works because the all of the tasks in group exits are killed with schedule_task_exit_locked. For clarity the code in get_signal has been updated to call do_exit instead of do_group_exit when a single task is exiting. While this schedule_task_exit_locked is a generalization of what happens in prepare_signal I do not change prepare_signal to use schedule_task_exit_locked to deliver SIGKILL to a coredumping process. This keeps all of the specialness delivering a signal to a coredumping process limited to prepare_signal and the coredump code itself. Signed-off-by: "Eric W. Biederman" --- fs/coredump.c | 7 ++----- include/linux/sched/signal.h | 2 ++ kernel/signal.c | 36 +++++++++++++++++++++--------------- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index 09302a6a0d80..9559e29daada 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -358,12 +358,9 @@ static int zap_process(struct task_struct *start, int = exit_code) start->signal->group_stop_count =3D 0; =20 for_each_thread(start, t) { - task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK); - if (t !=3D current && !(t->flags & PF_POSTCOREDUMP)) { - sigaddset(&t->pending.signal, SIGKILL); - signal_wake_up(t, 1); + schedule_task_exit_locked(t); + if (t !=3D current && !(t->flags & PF_POSTCOREDUMP)) nr++; - } } =20 return nr; diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index b6ecb9fc4cd2..7c62b7c29cc0 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -427,6 +427,8 @@ static inline void ptrace_signal_wake_up(struct task_st= ruct *t, bool resume) signal_wake_up_state(t, resume ? __TASK_TRACED : 0); } =20 +void schedule_task_exit_locked(struct task_struct *task); + void task_join_group_stop(struct task_struct *task); =20 #ifdef TIF_RESTORE_SIGMASK diff --git a/kernel/signal.c b/kernel/signal.c index 2a24cca00ca1..cbfb9020368e 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1056,9 +1056,7 @@ static void complete_signal(int sig, struct task_stru= ct *p, enum pid_type type) signal->group_stop_count =3D 0; t =3D p; do { - task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK); - sigaddset(&t->pending.signal, SIGKILL); - signal_wake_up(t, 1); + schedule_task_exit_locked(t); } while_each_thread(p, t); return; } @@ -1363,6 +1361,16 @@ int force_sig_info(struct kernel_siginfo *info) return force_sig_info_to_task(info, current, HANDLER_CURRENT); } =20 +void schedule_task_exit_locked(struct task_struct *task) +{ + task_clear_jobctl_pending(task, JOBCTL_PENDING_MASK); + /* Only bother with threads that might be alive */ + if (!(task->flags & PF_POSTCOREDUMP)) { + sigaddset(&task->pending.signal, SIGKILL); + signal_wake_up(task, 1); + } +} + /* * Nuke all other threads in the group. */ @@ -1374,16 +1382,9 @@ int zap_other_threads(struct task_struct *p) p->signal->group_stop_count =3D 0; =20 while_each_thread(p, t) { - task_clear_jobctl_pending(t, JOBCTL_PENDING_MASK); count++; - - /* Don't bother with already dead threads */ - if (t->exit_state) - continue; - sigaddset(&t->pending.signal, SIGKILL); - signal_wake_up(t, 1); + schedule_task_exit_locked(t); } - return count; } =20 @@ -2706,12 +2707,12 @@ bool get_signal(struct ksignal *ksig) =20 for (;;) { struct k_sigaction *ka; + bool group_exit =3D true; enum pid_type type; int exit_code; =20 /* Has this task already been marked for death? */ - if ((signal->flags & SIGNAL_GROUP_EXIT) || - signal->group_exec_task) { + if (__fatal_signal_pending(current)) { ksig->info.si_signo =3D signr =3D SIGKILL; sigdelset(¤t->pending.signal, SIGKILL); trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO, @@ -2719,8 +2720,10 @@ bool get_signal(struct ksignal *ksig) recalc_sigpending(); if (signal->flags & SIGNAL_GROUP_EXIT) exit_code =3D signal->group_exit_code; - else + else { exit_code =3D 0; + group_exit =3D false; + } goto fatal; } =20 @@ -2880,7 +2883,10 @@ bool get_signal(struct ksignal *ksig) /* * Death signals, no core dump. */ - do_group_exit(exit_code); + if (group_exit) + do_group_exit(exit_code); + else + do_exit(exit_code); /* NOTREACHED */ } spin_unlock_irq(&sighand->siglock); --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A50FEC433F5 for ; Mon, 3 Jan 2022 21:34:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230090AbiACVe1 (ORCPT ); Mon, 3 Jan 2022 16:34:27 -0500 Received: from out01.mta.xmission.com ([166.70.13.231]:55768 "EHLO out01.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230256AbiACVeF (ORCPT ); Mon, 3 Jan 2022 16:34:05 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:54410) by out01.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxw-008wD7-RU; Mon, 03 Jan 2022 14:34:04 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxv-006zvm-8s; Mon, 03 Jan 2022 14:34:04 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:09 -0600 Message-Id: <20220103213312.9144-14-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxv-006zvm-8s;;;mid=<20220103213312.9144-14-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1/7rKcji5T4omSxiJmES4YaISAldVmmCdw= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 14/17] signal: Remove zap_other_threads X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The two callers of zap_other_threads want different things. The function do_group_exit wants to set the exit code and it does not care about the number of threads exiting. In de_thread the current thread is not exiting so there is not really an exit code. Since schedule_task_exit_locked factors out the tricky bits stop sharing the loop in zap_other_threads between de_thread and do_group_exit. Signed-off-by: "Eric W. Biederman" --- fs/exec.c | 12 +++++++++--- include/linux/sched/signal.h | 1 - kernel/exit.c | 9 ++++++++- kernel/signal.c | 17 ----------------- 4 files changed, 17 insertions(+), 22 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 82db656ca709..b9f646fddc51 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1037,6 +1037,7 @@ static int de_thread(struct task_struct *tsk) struct signal_struct *sig =3D tsk->signal; struct sighand_struct *oldsighand =3D tsk->sighand; spinlock_t *lock =3D &oldsighand->siglock; + struct task_struct *t; =20 if (thread_group_empty(tsk)) goto no_thread_group; @@ -1055,9 +1056,14 @@ static int de_thread(struct task_struct *tsk) } =20 sig->group_exec_task =3D tsk; - sig->notify_count =3D zap_other_threads(tsk); - if (!thread_group_leader(tsk)) - sig->notify_count--; + sig->group_stop_count =3D 0; + sig->notify_count =3D 0; + __for_each_thread(sig, t) { + if (t =3D=3D tsk) + continue; + sig->notify_count++; + schedule_task_exit_locked(t); + } =20 while (sig->notify_count) { __set_current_state(TASK_KILLABLE); diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 7c62b7c29cc0..eed54f9ea2fc 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -343,7 +343,6 @@ extern void force_sig(int); extern void force_fatal_sig(int); extern void force_exit_sig(int); extern int send_sig(int, struct task_struct *, int); -extern int zap_other_threads(struct task_struct *p); extern struct sigqueue *sigqueue_alloc(void); extern void sigqueue_free(struct sigqueue *); extern int send_sigqueue(struct sigqueue *, struct pid *, enum pid_type); diff --git a/kernel/exit.c b/kernel/exit.c index aedefe5eb0eb..27bc0ccfea78 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -918,9 +918,16 @@ do_group_exit(int exit_code) else if (sig->group_exec_task) exit_code =3D 0; else { + struct task_struct *t; + sig->group_exit_code =3D exit_code; sig->flags =3D SIGNAL_GROUP_EXIT; - zap_other_threads(current); + sig->group_stop_count =3D 0; + __for_each_thread(sig, t) { + if (t =3D=3D current) + continue; + schedule_task_exit_locked(t); + } } spin_unlock_irq(&sighand->siglock); } diff --git a/kernel/signal.c b/kernel/signal.c index cbfb9020368e..b0201e05be40 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1371,23 +1371,6 @@ void schedule_task_exit_locked(struct task_struct *t= ask) } } =20 -/* - * Nuke all other threads in the group. - */ -int zap_other_threads(struct task_struct *p) -{ - struct task_struct *t =3D p; - int count =3D 0; - - p->signal->group_stop_count =3D 0; - - while_each_thread(p, t) { - count++; - schedule_task_exit_locked(t); - } - return count; -} - struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, unsigned long *flags) { --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1B96AC433F5 for ; Mon, 3 Jan 2022 21:34:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230380AbiACVec (ORCPT ); Mon, 3 Jan 2022 16:34:32 -0500 Received: from out02.mta.xmission.com ([166.70.13.232]:53518 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230283AbiACVeH (ORCPT ); Mon, 3 Jan 2022 16:34:07 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:59342) by out02.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxz-008tnC-5U; Mon, 03 Jan 2022 14:34:07 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uxy-006zvm-0t; Mon, 03 Jan 2022 14:34:06 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:10 -0600 Message-Id: <20220103213312.9144-15-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uxy-006zvm-0t;;;mid=<20220103213312.9144-15-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX19WsUgJ+H/UpszfMEuPnr4iNIjMQzk65Hk= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 15/17] signal: Add JOBCTL_WILL_EXIT to mark exiting tasks X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Mark tasks that need to exit with JOBCTL_WILL_EXIT instead of reusing the per thread SIGKILL. This removes the double meaning of the per thread SIGKILL and makes it possible to detect when a task has already been scheduled for exiting and to skip unnecessary work if the task is already scheduled to exit. A jobctl flag was choosen for this purpose because jobctl changes are protected by siglock, and updates are already careful not to change or clear other bits in jobctl. Protection by a lock when changing the value is necessary as JOBCTL_WILL_EXIT will not be limited to being set by the current task. That task->jobctl is protected by siglock is convenient as siglock is already held everywhere I want to set or reset JOBCTL_WILL_EXIT. Teach wants_signal and retarget_shared_pending to use JOBCTL_TASK_EXITING to detect threads that have an exit pending and so will not be processing any more signals. Signed-off-by: "Eric W. Biederman" --- fs/coredump.c | 6 ++++-- include/linux/sched/jobctl.h | 2 ++ include/linux/sched/signal.h | 2 +- kernel/exit.c | 4 ++-- kernel/signal.c | 19 +++++++++---------- 5 files changed, 18 insertions(+), 15 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index 9559e29daada..4e82ee51633d 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -352,7 +352,6 @@ static int zap_process(struct task_struct *start, int e= xit_code) struct task_struct *t; int nr =3D 0; =20 - /* Allow SIGKILL, see prepare_signal() */ start->signal->flags =3D SIGNAL_GROUP_EXIT; start->signal->group_exit_code =3D exit_code; start->signal->group_stop_count =3D 0; @@ -376,9 +375,11 @@ static int zap_threads(struct task_struct *tsk, if (!(signal->flags & SIGNAL_GROUP_EXIT) && !signal->group_exec_task) { signal->core_state =3D core_state; nr =3D zap_process(tsk, exit_code); + atomic_set(&core_state->nr_threads, nr); + /* Allow SIGKILL, see prepare_signal() */ clear_tsk_thread_flag(tsk, TIF_SIGPENDING); tsk->flags |=3D PF_DUMPCORE; - atomic_set(&core_state->nr_threads, nr); + tsk->jobctl &=3D ~JOBCTL_WILL_EXIT; } spin_unlock_irq(&tsk->sighand->siglock); return nr; @@ -425,6 +426,7 @@ static void coredump_finish(bool core_dumped) current->signal->group_exit_code |=3D 0x80; next =3D current->signal->core_state->dumper.next; current->signal->core_state =3D NULL; + current->jobctl |=3D JOBCTL_WILL_EXIT; spin_unlock_irq(¤t->sighand->siglock); =20 while ((curr =3D next) !=3D NULL) { diff --git a/include/linux/sched/jobctl.h b/include/linux/sched/jobctl.h index fa067de9f1a9..9887d737ccfb 100644 --- a/include/linux/sched/jobctl.h +++ b/include/linux/sched/jobctl.h @@ -19,6 +19,7 @@ struct task_struct; #define JOBCTL_TRAPPING_BIT 21 /* switching to TRACED */ #define JOBCTL_LISTENING_BIT 22 /* ptracer is listening for events */ #define JOBCTL_TRAP_FREEZE_BIT 23 /* trap for cgroup freezer */ +#define JOBCTL_WILL_EXIT_BIT 31 /* task will exit */ =20 #define JOBCTL_STOP_DEQUEUED (1UL << JOBCTL_STOP_DEQUEUED_BIT) #define JOBCTL_STOP_PENDING (1UL << JOBCTL_STOP_PENDING_BIT) @@ -28,6 +29,7 @@ struct task_struct; #define JOBCTL_TRAPPING (1UL << JOBCTL_TRAPPING_BIT) #define JOBCTL_LISTENING (1UL << JOBCTL_LISTENING_BIT) #define JOBCTL_TRAP_FREEZE (1UL << JOBCTL_TRAP_FREEZE_BIT) +#define JOBCTL_WILL_EXIT (1UL << JOBCTL_WILL_EXIT_BIT) =20 #define JOBCTL_TRAP_MASK (JOBCTL_TRAP_STOP | JOBCTL_TRAP_NOTIFY) #define JOBCTL_PENDING_MASK (JOBCTL_STOP_PENDING | JOBCTL_TRAP_MASK) diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index eed54f9ea2fc..989bb665f107 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -373,7 +373,7 @@ static inline int signal_pending(struct task_struct *p) =20 static inline int __fatal_signal_pending(struct task_struct *p) { - return unlikely(sigismember(&p->pending.signal, SIGKILL)); + return unlikely(p->jobctl & JOBCTL_WILL_EXIT); } =20 static inline int fatal_signal_pending(struct task_struct *p) diff --git a/kernel/exit.c b/kernel/exit.c index 27bc0ccfea78..7a7a0cbac28e 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -906,7 +906,7 @@ do_group_exit(int exit_code) =20 if (sig->flags & SIGNAL_GROUP_EXIT) exit_code =3D sig->group_exit_code; - else if (sig->group_exec_task) + else if (current->jobctl & JOBCTL_WILL_EXIT) exit_code =3D 0; else if (!thread_group_empty(current)) { struct sighand_struct *const sighand =3D current->sighand; @@ -915,7 +915,7 @@ do_group_exit(int exit_code) if (sig->flags & SIGNAL_GROUP_EXIT) /* Another thread got here before we took the lock. */ exit_code =3D sig->group_exit_code; - else if (sig->group_exec_task) + else if (current->jobctl & JOBCTL_WILL_EXIT) exit_code =3D 0; else { struct task_struct *t; diff --git a/kernel/signal.c b/kernel/signal.c index b0201e05be40..6179e34ce666 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -153,7 +153,8 @@ static inline bool has_pending_signals(sigset_t *signal= , sigset_t *blocked) =20 static bool recalc_sigpending_tsk(struct task_struct *t) { - if ((t->jobctl & (JOBCTL_PENDING_MASK | JOBCTL_TRAP_FREEZE)) || + if ((t->jobctl & (JOBCTL_PENDING_MASK | JOBCTL_TRAP_FREEZE | + JOBCTL_WILL_EXIT)) || PENDING(&t->pending, &t->blocked) || PENDING(&t->signal->shared_pending, &t->blocked) || cgroup_task_frozen(t)) { @@ -911,7 +912,7 @@ static bool prepare_signal(int sig, struct task_struct = *p, bool force) if (core_state) { if (sig =3D=3D SIGKILL) { struct task_struct *dumper =3D core_state->dumper.task; - sigaddset(&dumper->pending.signal, SIGKILL); + dumper->jobctl |=3D JOBCTL_WILL_EXIT; signal_wake_up(dumper, 1); } } @@ -985,7 +986,7 @@ static inline bool wants_signal(int sig, struct task_st= ruct *p) if (sigismember(&p->blocked, sig)) return false; =20 - if (p->flags & PF_EXITING) + if (p->jobctl & JOBCTL_WILL_EXIT) return false; =20 if (sig =3D=3D SIGKILL) @@ -1363,10 +1364,9 @@ int force_sig_info(struct kernel_siginfo *info) =20 void schedule_task_exit_locked(struct task_struct *task) { - task_clear_jobctl_pending(task, JOBCTL_PENDING_MASK); - /* Only bother with threads that might be alive */ - if (!(task->flags & PF_POSTCOREDUMP)) { - sigaddset(&task->pending.signal, SIGKILL); + if (!(task->jobctl & JOBCTL_WILL_EXIT)) { + task_clear_jobctl_pending(task, JOBCTL_PENDING_MASK); + task->jobctl |=3D JOBCTL_WILL_EXIT; signal_wake_up(task, 1); } } @@ -2695,9 +2695,8 @@ bool get_signal(struct ksignal *ksig) int exit_code; =20 /* Has this task already been marked for death? */ - if (__fatal_signal_pending(current)) { + if (current->jobctl & JOBCTL_WILL_EXIT) { ksig->info.si_signo =3D signr =3D SIGKILL; - sigdelset(¤t->pending.signal, SIGKILL); trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO, &sighand->action[SIGKILL - 1]); recalc_sigpending(); @@ -2935,7 +2934,7 @@ static void retarget_shared_pending(struct task_struc= t *tsk, sigset_t *which) =20 t =3D tsk; while_each_thread(tsk, t) { - if (t->flags & PF_EXITING) + if (t->jobctl & JOBCTL_WILL_EXIT) continue; =20 if (!has_pending_signals(&retarget, &t->blocked)) --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B9F2C433FE for ; Mon, 3 Jan 2022 21:34:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230300AbiACVea (ORCPT ); Mon, 3 Jan 2022 16:34:30 -0500 Received: from out02.mta.xmission.com ([166.70.13.232]:53544 "EHLO out02.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230311AbiACVeL (ORCPT ); Mon, 3 Jan 2022 16:34:11 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:59418) by out02.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uy2-008tne-AD; Mon, 03 Jan 2022 14:34:10 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uy0-006zvm-9C; Mon, 03 Jan 2022 14:34:08 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:11 -0600 Message-Id: <20220103213312.9144-16-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uy0-006zvm-9C;;;mid=<20220103213312.9144-16-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1/OVBiRPGvA36vV0sSJn7+q19HoR7Q84/s= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 16/17] signal: Record the exit_code when an exit is scheduled X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" With ptrace_stop no longer using task->exit_code it is safe to set task->exit_code when an exit is scheduled. Use the bit JOBCTL_WILL_EXIT to detect when a exit is first scheduled and only set exit_code the first time. Only use the code provided to do_exit if the task has not yet been schedled to exit. In get_signal and do_grup_exit when JOBCTL_WILL_EXIT is set read the recored exit_code from current->exit_code, instead of assuming exit_code will always be 0. Signed-off-by: "Eric W. Biederman" --- fs/coredump.c | 2 +- fs/exec.c | 2 +- include/linux/sched/signal.h | 2 +- kernel/exit.c | 12 ++++++++---- kernel/signal.c | 7 ++++--- 5 files changed, 15 insertions(+), 10 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index 4e82ee51633d..c54b502bf648 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -357,7 +357,7 @@ static int zap_process(struct task_struct *start, int e= xit_code) start->signal->group_stop_count =3D 0; =20 for_each_thread(start, t) { - schedule_task_exit_locked(t); + schedule_task_exit_locked(t, exit_code); if (t !=3D current && !(t->flags & PF_POSTCOREDUMP)) nr++; } diff --git a/fs/exec.c b/fs/exec.c index b9f646fddc51..3203605e54cb 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1062,7 +1062,7 @@ static int de_thread(struct task_struct *tsk) if (t =3D=3D tsk) continue; sig->notify_count++; - schedule_task_exit_locked(t); + schedule_task_exit_locked(t, 0); } =20 while (sig->notify_count) { diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 989bb665f107..e8034ecaee84 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -426,7 +426,7 @@ static inline void ptrace_signal_wake_up(struct task_st= ruct *t, bool resume) signal_wake_up_state(t, resume ? __TASK_TRACED : 0); } =20 -void schedule_task_exit_locked(struct task_struct *task); +void schedule_task_exit_locked(struct task_struct *task, int exit_code); =20 void task_join_group_stop(struct task_struct *task); =20 diff --git a/kernel/exit.c b/kernel/exit.c index 7a7a0cbac28e..e95500e2d27c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -735,6 +735,11 @@ void __noreturn do_exit(long code) struct task_struct *tsk =3D current; int group_dead; =20 + spin_lock_irq(&tsk->sighand->siglock); + schedule_task_exit_locked(tsk, code); + code =3D tsk->exit_code; + spin_unlock_irq(&tsk->sighand->siglock); + WARN_ON(blk_needs_flush_plug(tsk)); =20 kcov_task_exit(tsk); @@ -773,7 +778,6 @@ void __noreturn do_exit(long code) tty_audit_exit(); audit_free(tsk); =20 - tsk->exit_code =3D code; taskstats_exit(tsk, group_dead); =20 exit_mm(); @@ -907,7 +911,7 @@ do_group_exit(int exit_code) if (sig->flags & SIGNAL_GROUP_EXIT) exit_code =3D sig->group_exit_code; else if (current->jobctl & JOBCTL_WILL_EXIT) - exit_code =3D 0; + exit_code =3D current->exit_code; else if (!thread_group_empty(current)) { struct sighand_struct *const sighand =3D current->sighand; =20 @@ -916,7 +920,7 @@ do_group_exit(int exit_code) /* Another thread got here before we took the lock. */ exit_code =3D sig->group_exit_code; else if (current->jobctl & JOBCTL_WILL_EXIT) - exit_code =3D 0; + exit_code =3D current->exit_code; else { struct task_struct *t; =20 @@ -926,7 +930,7 @@ do_group_exit(int exit_code) __for_each_thread(sig, t) { if (t =3D=3D current) continue; - schedule_task_exit_locked(t); + schedule_task_exit_locked(t, exit_code); } } spin_unlock_irq(&sighand->siglock); diff --git a/kernel/signal.c b/kernel/signal.c index 6179e34ce666..e8fac8a3c935 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1057,7 +1057,7 @@ static void complete_signal(int sig, struct task_stru= ct *p, enum pid_type type) signal->group_stop_count =3D 0; t =3D p; do { - schedule_task_exit_locked(t); + schedule_task_exit_locked(t, sig); } while_each_thread(p, t); return; } @@ -1362,11 +1362,12 @@ int force_sig_info(struct kernel_siginfo *info) return force_sig_info_to_task(info, current, HANDLER_CURRENT); } =20 -void schedule_task_exit_locked(struct task_struct *task) +void schedule_task_exit_locked(struct task_struct *task, int exit_code) { if (!(task->jobctl & JOBCTL_WILL_EXIT)) { task_clear_jobctl_pending(task, JOBCTL_PENDING_MASK); task->jobctl |=3D JOBCTL_WILL_EXIT; + task->exit_code =3D exit_code; signal_wake_up(task, 1); } } @@ -2703,7 +2704,7 @@ bool get_signal(struct ksignal *ksig) if (signal->flags & SIGNAL_GROUP_EXIT) exit_code =3D signal->group_exit_code; else { - exit_code =3D 0; + exit_code =3D current->exit_code; group_exit =3D false; } goto fatal; --=20 2.29.2 From nobody Wed Jul 1 03:08:25 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 22F30C433F5 for ; Mon, 3 Jan 2022 21:34:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230412AbiACVef (ORCPT ); Mon, 3 Jan 2022 16:34:35 -0500 Received: from out03.mta.xmission.com ([166.70.13.233]:45950 "EHLO out03.mta.xmission.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230106AbiACVeP (ORCPT ); Mon, 3 Jan 2022 16:34:15 -0500 Received: from in02.mta.xmission.com ([166.70.13.52]:57238) by out03.mta.xmission.com with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uy6-00ET2Z-UJ; Mon, 03 Jan 2022 14:34:14 -0700 Received: from ip68-110-24-146.om.om.cox.net ([68.110.24.146]:54408 helo=localhost.localdomain) by in02.mta.xmission.com with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.93) (envelope-from ) id 1n4Uy3-006zvm-E6; Mon, 03 Jan 2022 14:34:14 -0700 From: "Eric W. Biederman" To: linux-kernel@vger.kernel.org Cc: linux-arch@vger.kernel.org, Linus Torvalds , Oleg Nesterov , Al Viro , Kees Cook , linux-api@vger.kernel.org, "Eric W. Biederman" Date: Mon, 3 Jan 2022 15:33:12 -0600 Message-Id: <20220103213312.9144-17-ebiederm@xmission.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> References: <87r19opkx1.fsf_-_@email.froward.int.ebiederm.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-XM-SPF: eid=1n4Uy3-006zvm-E6;;;mid=<20220103213312.9144-17-ebiederm@xmission.com>;;;hst=in02.mta.xmission.com;;;ip=68.110.24.146;;;frm=ebiederm@xmission.com;;;spf=neutral X-XM-AID: U2FsdGVkX1/n11MnW3+3bV0i/GFwB5zyneexXh1Bojw= X-SA-Exim-Connect-IP: 68.110.24.146 X-SA-Exim-Mail-From: ebiederm@xmission.com Subject: [PATCH 17/17] signal: Always set SIGNAL_GROUP_EXIT on process exit X-SA-Exim-Version: 4.2.1 (built Sat, 08 Feb 2020 21:53:50 +0000) X-SA-Exim-Scanned: Yes (on in02.mta.xmission.com) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Track how many threads have not started exiting and when the last thread starts exiting set SIGNAL_GROUP_EXIT. Signed-off-by: "Eric W. Biederman" --- fs/coredump.c | 4 ---- include/linux/sched/signal.h | 1 + kernel/exit.c | 8 +------- kernel/fork.c | 2 ++ kernel/signal.c | 10 +++++++--- 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/fs/coredump.c b/fs/coredump.c index c54b502bf648..029d0f98aa90 100644 --- a/fs/coredump.c +++ b/fs/coredump.c @@ -352,10 +352,6 @@ static int zap_process(struct task_struct *start, int = exit_code) struct task_struct *t; int nr =3D 0; =20 - start->signal->flags =3D SIGNAL_GROUP_EXIT; - start->signal->group_exit_code =3D exit_code; - start->signal->group_stop_count =3D 0; - for_each_thread(start, t) { schedule_task_exit_locked(t, exit_code); if (t !=3D current && !(t->flags & PF_POSTCOREDUMP)) diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index e8034ecaee84..bd9435e934a1 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -94,6 +94,7 @@ struct signal_struct { refcount_t sigcnt; atomic_t live; int nr_threads; + int quick_threads; struct list_head thread_head; =20 wait_queue_head_t wait_chldexit; /* for wait4() */ diff --git a/kernel/exit.c b/kernel/exit.c index e95500e2d27c..be867a12de65 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -924,14 +924,8 @@ do_group_exit(int exit_code) else { struct task_struct *t; =20 - sig->group_exit_code =3D exit_code; - sig->flags =3D SIGNAL_GROUP_EXIT; - sig->group_stop_count =3D 0; - __for_each_thread(sig, t) { - if (t =3D=3D current) - continue; + __for_each_thread(sig, t) schedule_task_exit_locked(t, exit_code); - } } spin_unlock_irq(&sighand->siglock); } diff --git a/kernel/fork.c b/kernel/fork.c index 6f0293cb29c9..d973189a4014 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1644,6 +1644,7 @@ static int copy_signal(unsigned long clone_flags, str= uct task_struct *tsk) return -ENOMEM; =20 sig->nr_threads =3D 1; + sig->quick_threads =3D 1; atomic_set(&sig->live, 1); refcount_set(&sig->sigcnt, 1); =20 @@ -2383,6 +2384,7 @@ static __latent_entropy struct task_struct *copy_proc= ess( __this_cpu_inc(process_counts); } else { current->signal->nr_threads++; + current->signal->quick_threads++; atomic_inc(¤t->signal->live); refcount_inc(¤t->signal->sigcnt); task_join_group_stop(p); diff --git a/kernel/signal.c b/kernel/signal.c index e8fac8a3c935..9bd835fcb1dc 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1052,9 +1052,6 @@ static void complete_signal(int sig, struct task_stru= ct *p, enum pid_type type) * running and doing things after a slower * thread has the fatal signal pending. */ - signal->flags =3D SIGNAL_GROUP_EXIT; - signal->group_exit_code =3D sig; - signal->group_stop_count =3D 0; t =3D p; do { schedule_task_exit_locked(t, sig); @@ -1365,10 +1362,17 @@ int force_sig_info(struct kernel_siginfo *info) void schedule_task_exit_locked(struct task_struct *task, int exit_code) { if (!(task->jobctl & JOBCTL_WILL_EXIT)) { + struct signal_struct *signal =3D task->signal; task_clear_jobctl_pending(task, JOBCTL_PENDING_MASK); task->jobctl |=3D JOBCTL_WILL_EXIT; task->exit_code =3D exit_code; signal_wake_up(task, 1); + signal->quick_threads--; + if (signal->quick_threads =3D=3D 0) { + signal->flags =3D SIGNAL_GROUP_EXIT; + signal->group_exit_code =3D exit_code; + signal->group_stop_count =3D 0; + } } } =20 --=20 2.29.2