Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3126974imu; Fri, 18 Jan 2019 05:21:00 -0800 (PST) X-Google-Smtp-Source: ALg8bN5SR8FrsZcRlPNZ8Qc4b3NFdwbwAQ0KfTaDygtR7DtXZkw3l/amN0t1vHwpJmDgaS4muynj X-Received: by 2002:a63:5252:: with SMTP id s18mr17581275pgl.326.1547817660616; Fri, 18 Jan 2019 05:21:00 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1547817660; cv=none; d=google.com; s=arc-20160816; b=dH27TK/4btlbqpL8m9R7TWqwaFIlMxoku6svDfP1afVu5ToyW7Y7HGP2ofkO2aHDhG 8wgP5Wx862DVpTpn6p2amg4sy1lXy+3F59ryG2f7A4vrrUEZEgekZEg91klzPvHeVUSG 66NfijcrW0M8319bkYRFV4fH/4jhfj5LOo8B26zqvrMWZB4kRUwu4DlSKoWTNLihhoOW fCiY7UPiGc3EdGFVB72xMnBa3ivXIIxZulS9B6qcBWQ0QsMdxFcN9IQBC0++n+sxVVlV CvjX4XON6ot9Su3IZhwi3QkbNyr8GgtSeBgLPnNmDv0jEaWBOt4ttdxxGK6acUu7BI1u ouXg== 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=HFgwW/0ex/QdQ3lHvpk6FRs21O+CjQtnrdZhaUFPDNM=; b=Q9rg+sJTYpl5FtUkkgu4qpAXf68UvONOL+E07j+Mv9EHyyg6905Ok6RkfgvTWkNo55 BwNH9oiG4GwRiU8vDO2qaoud/h2CDL/NC41kEsxXHAazZCZgOZbtSxfr/JFacB7fvE0k 0gXV87fdBoDMOYlFF8OUn79aThw9IXYFNziMuEDFnoyLB8Ld8XFi6dH1mc7Pwx+MMTW3 a2AmPp25jFkTu0NR62ysmhXNE7bs/vr4nnDogekBaz5UUYSnGGBJe0ya0s0+6tsEpVuY raH+qIY5ooXDzWJo2taGvRmgUQWoIxVDbrWWqxYT8vTxfdgl0mhOBURGiL8sZmHt7dPV c0Ug== 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 cb1si4610830plb.37.2019.01.18.05.20.41; Fri, 18 Jan 2019 05:21:00 -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 S1727406AbfARNTX (ORCPT + 99 others); Fri, 18 Jan 2019 08:19:23 -0500 Received: from nov-007-i650.relay.mailchannels.net ([46.232.183.204]:20723 "EHLO nov-007-i650.relay.mailchannels.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727100AbfARNTW (ORCPT ); Fri, 18 Jan 2019 08:19:22 -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 5DB671B6070D; Fri, 18 Jan 2019 13:12:01 +0000 (UTC) Received: from srv17.tophost.ch (swiss-ingress-2.mailchannels.ch [46.232.183.6]) by relay.mailchannels.net (Postfix) with ESMTPA id AE8631B6071F; Fri, 18 Jan 2019 13:11:57 +0000 (UTC) X-Sender-Id: novatrend|x-authuser|juerg@bitron.ch Received: from srv17.tophost.ch (srv17.tophost.ch [193.33.128.155]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.15.2); Fri, 18 Jan 2019 13:12:01 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: novatrend|x-authuser|juerg@bitron.ch X-MailChannels-Auth-Id: novatrend X-Suffer-Inform: 31bbb35b02dccf1f_1547817121100_740928673 X-MC-Loop-Signature: 1547817121100:2132902996 X-MC-Ingress-Time: 1547817121100 Received: from [80.219.231.201] (port=59124 helo=jzen.bitron.ch) by srv17.tophost.ch with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-SHA256:128) (Exim 4.91) (envelope-from ) id 1gkTwA-0002In-EE; Fri, 18 Jan 2019 14:11:54 +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: [RESEND PATCH v2 1/1] prctl: add PR_{GET,SET}_KILL_DESCENDANTS_ON_EXIT Date: Fri, 18 Jan 2019 14:11:30 +0100 Message-Id: <20190118131130.42209-2-j@bitron.ch> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190118131130.42209-1-j@bitron.ch> References: <20181127225408.7553-1-j@bitron.ch> <20190118131130.42209-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 Reviewed-by: Oleg Nesterov --- 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 fb72d36f7823..bbb5a0718223 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1342,6 +1342,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 = false; + /* * 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 13789d10a50e..2acf481951f6 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 */ + bool kill_descendants_on_exit; + #ifdef CONFIG_POSIX_TIMERS /* POSIX.1b Interval Timers */ diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index b4875a93363a..d5483ca63c2d 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 2d14979577ee..93a812c1b670 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 f7eb62eceb24..f6dba0ba9b77 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2485,6 +2485,17 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, return -EINVAL; error = PAC_RESET_KEYS(me, arg2); 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 2c010874329f..b09c6e0a25ff 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -698,6 +698,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 = false; /* 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 f0e36c3492ba..3bac775634c8 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2510,6 +2510,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 = false; + /* 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.20.1