Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp434920imu; Tue, 27 Nov 2018 14:56:41 -0800 (PST) X-Google-Smtp-Source: AFSGD/UEUtqTd9O3zUYNVvZUgiBoXCqn6QeWBYXyYren2nj4EVUPHRloJij3y5CrBq10qi5Q/UBn X-Received: by 2002:a17:902:280b:: with SMTP id e11mr34487005plb.269.1543359401116; Tue, 27 Nov 2018 14:56:41 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1543359401; cv=none; d=google.com; s=arc-20160816; b=lnhGTyqCrlY3xCumi7UtdEqkzv8Ix2OTlL0XruMcCYJ8+3c18i7PNmKXnz4xnU2jrj wn5T4X8uMdH03oaePkqEi+FsZIQHwFeccFKKlEuE+tTV/jDUeneqwnBtkIhY1XkNEdaN bte6DZkD1Sqh4EBVOXlsLAvHITR9lVx/iAaGDqT0Rrnq46TC0BcR7fZXZUO4+NdUYlZb 8t7vvc3gpDN7BbXqB+6d3GUKlBikXFnImel4iDa72RoDXsHWPQ+alL3jv0BO5ragtAlE NGcbL4Lrx1yU8Bapp8c19TVR6Yr6BeQC+oPA7NYB57MmbAD3cDjH2jIciwix2lP+INPR QMjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=4tzBzpGNNxJu/zS5uqqV9OhrjqKvfS7wAr8MnwPHtls=; b=MpBBTMa9vZtt9RheOtq8mDwsOiLuIg6JEKfqZpVMkQwLjV/9rQLAquwlTZbItRXYMw JGrirPJBrqe+9uYONUC4m9qAdACSQmE17DF8MnTKUfyHVhNPj0gXLv3ele+zEMuOchrP miZhLfzzYxaLlo82+KSiPRXFYGryQgw578m6ymUAhAzbk9wHLc0uIv25XNLkV77xDbyO b3sE7k1v3DsToMk3rY+ypGhzoBrg1dIkUQwfAGvPgxjc5E1DZCiLdnwpIaFy6o12Slw+ fxCBTyi0OxGDbYeq0gF7rJzV3d/ExyL6+b9kGZ7Cm041qIVCLUujY8DiexXlxiuwSI7f OHAA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t12si4877413plq.190.2018.11.27.14.56.26; Tue, 27 Nov 2018 14:56:41 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726872AbeK1Jye (ORCPT + 99 others); Wed, 28 Nov 2018 04:54:34 -0500 Received: from nov-007-i651.relay.mailchannels.net ([46.232.183.205]:11596 "EHLO nov-007-i651.relay.mailchannels.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726451AbeK1Jye (ORCPT ); Wed, 28 Nov 2018 04:54:34 -0500 X-Sender-Id: novatrend|x-authuser|juerg@bitron.ch Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 56E0E2EC0011; Tue, 27 Nov 2018 22:55:03 +0000 (UTC) Received: from srv17.tophost.ch (swiss-ingress-2.mailchannels.ch [46.232.183.6]) by relay.mailchannels.net (Postfix) with ESMTPA id F18162EC0008; Tue, 27 Nov 2018 22:54:59 +0000 (UTC) X-Sender-Id: novatrend|x-authuser|juerg@bitron.ch Received: from srv17.tophost.ch (srv17.tophost.ch [193.33.128.141]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.15.2); Tue, 27 Nov 2018 22:55:03 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: novatrend|x-authuser|juerg@bitron.ch X-MailChannels-Auth-Id: novatrend X-Belong-Chief: 3c87684f0dac1aa8_1543359303126_722207386 X-MC-Loop-Signature: 1543359303125:504231051 X-MC-Ingress-Time: 1543359303125 Received: from [88.98.246.21] (port=40458 helo=jx1y.mynet) by srv17.tophost.ch with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-SHA256:128) (Exim 4.91) (envelope-from ) id 1gRmFr-008hty-Je; Tue, 27 Nov 2018 23:54:55 +0100 From: =?UTF-8?q?J=C3=BCrg=20Billeter?= To: Andrew Morton Cc: Oleg Nesterov , Thomas Gleixner , Eric Biederman , Kees Cook , Andy Lutomirski , linux-api@vger.kernel.org, linux-kernel@vger.kernel.org, =?UTF-8?q?J=C3=BCrg=20Billeter?= Subject: [PATCH] prctl: add PR_{GET,SET}_KILL_DESCENDANTS_ON_EXIT Date: Tue, 27 Nov 2018 22:54:08 +0000 Message-Id: <20181127225408.7553-2-j@bitron.ch> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20181127225408.7553-1-j@bitron.ch> References: <20181127225408.7553-1-j@bitron.ch> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-AuthUser: juerg@bitron.ch Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This introduces a new thread group flag that can be set by calling prctl(PR_SET_KILL_DESCENDANTS_ON_EXIT, 1, 0, 0, 0) When a thread group exits with this flag set, it will send SIGKILL to all descendant processes. This can be used to prevent stray child processes. This flag is cleared on privilege gaining execve(2) to ensure an unprivileged process cannot get a privileged process to send SIGKILL. Descendants that are orphaned and reparented to an ancestor of the current process before the current process exits, will not be killed. PR_SET_CHILD_SUBREAPER can be used to contain orphaned processes. If a descendant gained privileges, the current process may not be allowed to kill it, and the descendant process will survive. PR_SET_NO_NEW_PRIVS can be used to prevent descendant processes from gaining privileges. Suggested-by: Oleg Nesterov Signed-off-by: Jürg Billeter --- fs/exec.c | 6 ++++++ include/linux/sched/signal.h | 3 +++ include/uapi/linux/prctl.h | 4 ++++ kernel/exit.c | 12 ++++++++++++ kernel/sys.c | 11 +++++++++++ security/apparmor/lsm.c | 1 + security/selinux/hooks.c | 3 +++ 7 files changed, 40 insertions(+) diff --git a/fs/exec.c b/fs/exec.c index 1ebf6e5a521d..f48ff4333393 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1339,6 +1339,12 @@ void setup_new_exec(struct linux_binprm * bprm) /* Make sure parent cannot signal privileged process. */ current->pdeath_signal = 0; + /* + * Do not send SIGKILL from privileged process as it may + * have been requested by an unprivileged process. + */ + current->signal->kill_descendants_on_exit = 0; + /* * For secureexec, reset the stack limit to sane default to * avoid bad behavior from the prior rlimits. This has to diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 1be35729c2c5..3bfb71701488 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -124,6 +124,9 @@ struct signal_struct { unsigned int is_child_subreaper:1; unsigned int has_child_subreaper:1; + /* Send SIGKILL to descendant processes on exit */ + unsigned int kill_descendants_on_exit:1; + #ifdef CONFIG_POSIX_TIMERS /* POSIX.1b Interval Timers */ diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index c0d7ea0bf5b6..2ac4da1f282b 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -198,6 +198,10 @@ struct prctl_mm_map { # define PR_CAP_AMBIENT_LOWER 3 # define PR_CAP_AMBIENT_CLEAR_ALL 4 +/* Send SIGKILL to descendant processes on exit */ +#define PR_SET_KILL_DESCENDANTS_ON_EXIT 48 +#define PR_GET_KILL_DESCENDANTS_ON_EXIT 49 + /* arm64 Scalable Vector Extension controls */ /* Flag values must be kept in sync with ptrace NT_ARM_SVE interface */ #define PR_SVE_SET_VL 50 /* set task vector length */ diff --git a/kernel/exit.c b/kernel/exit.c index 0e21e6d21f35..7fe0c694685a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -694,6 +694,15 @@ static void forget_original_parent(struct task_struct *father, list_splice_tail_init(&father->children, &reaper->children); } +static int kill_descendant_visitor(struct task_struct *p, void *data) +{ + /* This may fail, e.g., when a descendant process gained privileges. */ + group_send_sig_info(SIGKILL, SEND_SIG_NOINFO, p, PIDTYPE_TGID); + + /* Always continue walking the process tree. */ + return 1; +} + /* * Send signals to all our closest relatives so that they know * to properly mourn us.. @@ -704,6 +713,9 @@ static void exit_notify(struct task_struct *tsk, int group_dead) struct task_struct *p, *n; LIST_HEAD(dead); + if (group_dead && tsk->signal->kill_descendants_on_exit) + walk_process_tree(tsk, kill_descendant_visitor, NULL); + write_lock_irq(&tasklist_lock); forget_original_parent(tsk, &dead); diff --git a/kernel/sys.c b/kernel/sys.c index 123bd73046ec..8d9af81da093 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2476,6 +2476,17 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, return -EINVAL; error = arch_prctl_spec_ctrl_set(me, arg2, arg3); break; + case PR_SET_KILL_DESCENDANTS_ON_EXIT: + if (arg3 || arg4 || arg5) + return -EINVAL; + me->signal->kill_descendants_on_exit = !!arg2; + break; + case PR_GET_KILL_DESCENDANTS_ON_EXIT: + if (arg3 || arg4 || arg5) + return -EINVAL; + error = put_user(me->signal->kill_descendants_on_exit, + (int __user *)arg2); + break; default: error = -EINVAL; break; diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8b8b70620bbe..d0d8f88130fb 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -695,6 +695,7 @@ static void apparmor_bprm_committing_creds(struct linux_binprm *bprm) aa_inherit_files(bprm->cred, current->files); current->pdeath_signal = 0; + current->signal->kill_descendants_on_exit = 0; /* reset soft limits and set hard limits for the new label */ __aa_transition_rlimits(label, new_label); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ad9a9b8e9979..313a7be43a98 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2653,6 +2653,9 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) /* Always clear parent death signal on SID transitions. */ current->pdeath_signal = 0; + /* Disable SIGKILL requested from before the SID transition. */ + current->signal->kill_descendants_on_exit = 0; + /* Check whether the new SID can inherit resource limits from the old * SID. If not, reset all soft limits to the lower of the current * task's hard limit and the init task's soft limit. -- 2.19.2