Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp1919038imu; Wed, 12 Dec 2018 06:36:50 -0800 (PST) X-Google-Smtp-Source: AFSGD/UTTiy4+evMAqhPZYlg5uxAWrZC9kSFbpSktzXN7GTHS2jJMyz9NuFE/ae9JlRSSXtC7n7e X-Received: by 2002:a17:902:346:: with SMTP id 64mr20613378pld.337.1544625410884; Wed, 12 Dec 2018 06:36:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1544625410; cv=none; d=google.com; s=arc-20160816; b=MlCe+CEOJ14la6QkR04g610yjYfnWrasTAGwFa3Hutt1M9qluMuvESlZGlAtxjlBlX eYFxsCUt4aDAjaTM2gUDrxGAExSXxbVFZv+xbvUydk4u7llY9qCnlca+XVXuM6kx8vSs GtgocINGraVvZz2KvED4OAq6LrlwmjcCij7p0J+h7PAYbnugDb1AXCx0e0w7PQatM8lu tY+onA8lhYJ1nArJMjcAbGGHJ8vIXcUT6blwcILrS90elPQecgr5ph0IomUzpIks7Ecn ax2duhx/srquR9EAaRIO16pbyhK2nQcWe06nb+tZCbs71Ts8X4VDW0EKgYwm8WAQRXgI uTLA== 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 :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject:dkim-signature; bh=IeOnR2sSO6hz3SLLFGutz1VgE2zUOZSrE8RvgQ0QR2M=; b=qFRS6WlsDYi7WYa/1T5Qj0FZhxvKEAUmTCDYBlUWuKz8xe1OFLcTBJE615w4WfOMVQ n/HC98fpiefzU8n2BKxLItYUFtX66Fnp/yQKw5V17gvdiORRNKmbFEUm/RLlD94btLzd 9uACyYNzmZTVXRMDhXVv0n7jgmbi0r3e2AZEtvcujsC1i+9iaFHUofzjo8AeNceNyPm1 fkNcOQcN4NgGYNKWlDsL/o763hbZuoDAn+g4zNq4Y4bpkl296tPynmrDSeX12HuS4E9s 6N21NYYu3Pjn5xTNsXqFvo/LHftOk9Pv+V8fzSqveRH70jEZS2gRsSyl+n8NYQ+jFqhB wS0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@ssi.gouv.fr header.s=20160407 header.b=TJQyItkJ; 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 9si13742379pgn.524.2018.12.12.06.36.35; Wed, 12 Dec 2018 06:36:50 -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; dkim=pass header.i=@ssi.gouv.fr header.s=20160407 header.b=TJQyItkJ; 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 S1726688AbeLLOff (ORCPT + 99 others); Wed, 12 Dec 2018 09:35:35 -0500 Received: from smtp-out.ssi.gouv.fr ([86.65.182.90]:63385 "EHLO smtp-out.ssi.gouv.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726232AbeLLOfe (ORCPT ); Wed, 12 Dec 2018 09:35:34 -0500 X-Greylist: delayed 434 seconds by postgrey-1.27 at vger.kernel.org; Wed, 12 Dec 2018 09:35:33 EST Received: from smtp-out.ssi.gouv.fr (localhost [127.0.0.1]) by smtp-out.ssi.gouv.fr (Postfix) with ESMTP id A4D92D0006C; Wed, 12 Dec 2018 15:28:25 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ssi.gouv.fr; s=20160407; t=1544624905; bh=RURSNJxH3uXwyQWATCTsAZKmp59Lkaus4CuUmJ0TlvE=; h=Subject:To:CC:References:From:Date:In-Reply-To:From:Subject; b=TJQyItkJ40LvGdtGynmQhqS0iZOUMxq7wKc2iW3rOl/SnArM1DjIQhViE8hEc05R6 +NhQg/FC6q3qypYP2rvu/iTNS0YQUEw4cbnObozOuMYCnNLAf8kKnjdZMpVEUSDCP7 gmOoyxPn5wxmXwCesK+MNY74QJknnGfPMU8tpxBlrHE886J31wsHeMDFjnFGiDdZDc wTSZHd4/yhlKzHXnFXGdy/8PPkerTzmDRNpwYFbZd6Gv/7x4ktvkhxJaqgAS5egMWI c5gtPTJcS2u5UiaHVptbcoo5z7QXhBfJJkRYXViF1+n+Hta1/bLiHwwbolC8LKLjyY wCrqVt2Lh4MlA== Subject: Re: [RFC PATCH v1 3/5] Yama: Enforces noexec mounts or file executability through O_MAYEXEC To: CC: =?UTF-8?Q?Micka=c3=abl_Sala=c3=bcn?= , Al Viro , James Morris , Jonathan Corbet , Kees Cook , Matthew Garrett , Michael Kerrisk , Mimi Zohar , =?UTF-8?Q?Philippe_Tr=c3=a9buchet?= , Shuah Khan , Thibaut Sautereau , Vincent Strubel , Yves-Alexis Perez , , , , References: <20181212081712.32347-1-mic@digikod.net> <20181212081712.32347-4-mic@digikod.net> From: =?UTF-8?Q?Micka=c3=abl_Sala=c3=bcn?= Message-ID: <13fe4508-f0c0-66c7-8aab-8b3ccef5caa2@ssi.gouv.fr> Date: Wed, 12 Dec 2018 15:28:23 +0100 User-Agent: Mozilla/5.0 (X11; Linux i686; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: <20181212081712.32347-4-mic@digikod.net> Content-Type: text/plain; charset="utf-8" Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Le 12/12/2018 à 09:17, Mickaël Salaün a écrit : > Enable to either propagate the mount options from the underlying VFS > mount to prevent execution, or to propagate the file execute permission. > This may allow a script interpreter to check execution permissions > before reading commands from a file. > > The main goal is to be able to protect the kernel by restricting > arbitrary syscalls that an attacker could perform with a crafted binary > or certain script languages. It also improves multilevel isolation > by reducing the ability of an attacker to use side channels with > specific code. These restrictions can natively be enforced for ELF > binaries (with the noexec mount option) but require this kernel > extension to properly handle scripts (e.g., Python, Perl). > > Add a new sysctl kernel.yama.open_mayexec_enforce to control this > behavior. A following patch adds documentation. > > Signed-off-by: Mickaël Salaün > Reviewed-by: Philippe Trébuchet > Reviewed-by: Thibaut Sautereau > Cc: Kees Cook > Cc: Mickaël Salaün > --- > security/yama/Kconfig | 3 +- > security/yama/yama_lsm.c | 82 +++++++++++++++++++++++++++++++++++++++- > 2 files changed, 83 insertions(+), 2 deletions(-) > > diff --git a/security/yama/Kconfig b/security/yama/Kconfig > index 96b27405558a..9457619fabd5 100644 > --- a/security/yama/Kconfig > +++ b/security/yama/Kconfig > @@ -5,7 +5,8 @@ config SECURITY_YAMA > help > This selects Yama, which extends DAC support with additional > system-wide security settings beyond regular Linux discretionary > - access controls. Currently available is ptrace scope restriction. > + access controls. Currently available are ptrace scope restriction and > + enforcement of the O_MAYEXEC open flag. > Like capabilities, this security module stacks with other LSMs. > Further information can be found in > Documentation/admin-guide/LSM/Yama.rst. > diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c > index ffda91a4a1aa..120664e94ee5 100644 > --- a/security/yama/yama_lsm.c > +++ b/security/yama/yama_lsm.c > @@ -1,10 +1,12 @@ > /* > * Yama Linux Security Module > * > - * Author: Kees Cook > + * Authors: Kees Cook > + * Mickaël Salaün > * > * Copyright (C) 2010 Canonical, Ltd. > * Copyright (C) 2011 The Chromium OS Authors. > + * Copyright (C) 2018 ANSSI > * > * This program is free software; you can redistribute it and/or modify > * it under the terms of the GNU General Public License version 2, as > @@ -28,7 +30,14 @@ > #define YAMA_SCOPE_CAPABILITY 2 > #define YAMA_SCOPE_NO_ATTACH 3 > > +#define YAMA_OMAYEXEC_ENFORCE_NONE 0 > +#define YAMA_OMAYEXEC_ENFORCE_MOUNT (1 << 0) > +#define YAMA_OMAYEXEC_ENFORCE_FILE (1 << 1) > +#define _YAMA_OMAYEXEC_LAST YAMA_OMAYEXEC_ENFORCE_FILE > +#define _YAMA_OMAYEXEC_MASK ((_YAMA_OMAYEXEC_LAST << 1) - 1) > + > static int ptrace_scope = YAMA_SCOPE_RELATIONAL; > +static int open_mayexec_enforce = YAMA_OMAYEXEC_ENFORCE_NONE; > > /* describe a ptrace relationship for potential exception */ > struct ptrace_relation { > @@ -423,7 +432,40 @@ int yama_ptrace_traceme(struct task_struct *parent) > return rc; > } > > +/** > + * yama_inode_permission - check O_MAYEXEC permission before accessing an inode > + * @inode: inode structure to check > + * @mask: permission mask > + * > + * Return 0 if access is permitted, -EACCES otherwise. > + */ > +int yama_inode_permission(struct inode *inode, int mask) > +{ > + if (!(mask & MAY_OPENEXEC)) > + return 0; > + /* > + * Match regular files and directories to make it easier to > + * modify script interpreters. > + */ > + if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) > + return 0; I forgot to mention that these checks do not handle fifos. This is relevant in a threat model targeting persistent attacks (and with additional protections/restrictions). > + > + if ((open_mayexec_enforce & YAMA_OMAYEXEC_ENFORCE_MOUNT) && > + !(mask & MAY_EXECMOUNT)) > + return -EACCES; > + > + /* > + * May prefer acl_permission_check() instead of generic_permission(), > + * to not be bypassable with CAP_DAC_READ_SEARCH. > + */ > + if (open_mayexec_enforce & YAMA_OMAYEXEC_ENFORCE_FILE) > + return generic_permission(inode, MAY_EXEC); > + > + return 0; > +} > + > static struct security_hook_list yama_hooks[] __lsm_ro_after_init = { > + LSM_HOOK_INIT(inode_permission, yama_inode_permission), > LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), > LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), > LSM_HOOK_INIT(task_prctl, yama_task_prctl), > @@ -447,6 +489,37 @@ static int yama_dointvec_minmax(struct ctl_table *table, int write, > return proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos); > } > > +static int yama_dointvec_bitmask_macadmin(struct ctl_table *table, int write, > + void __user *buffer, size_t *lenp, > + loff_t *ppos) > +{ > + int error; > + > + if (write) { > + struct ctl_table table_copy; > + int tmp_mayexec_enforce; > + > + if (!capable(CAP_MAC_ADMIN)) > + return -EPERM; > + tmp_mayexec_enforce = *((int *)table->data); > + table_copy = *table; > + /* do not erase open_mayexec_enforce */ > + table_copy.data = &tmp_mayexec_enforce; > + error = proc_dointvec(&table_copy, write, buffer, lenp, ppos); > + if (error) > + return error; > + if ((tmp_mayexec_enforce | _YAMA_OMAYEXEC_MASK) != > + _YAMA_OMAYEXEC_MASK) > + return -EINVAL; > + *((int *)table->data) = tmp_mayexec_enforce; > + } else { > + error = proc_dointvec(table, write, buffer, lenp, ppos); > + if (error) > + return error; > + } > + return 0; > +} > + > static int zero; > static int max_scope = YAMA_SCOPE_NO_ATTACH; > > @@ -466,6 +539,13 @@ static struct ctl_table yama_sysctl_table[] = { > .extra1 = &zero, > .extra2 = &max_scope, > }, > + { > + .procname = "open_mayexec_enforce", > + .data = &open_mayexec_enforce, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = yama_dointvec_bitmask_macadmin, > + }, > { } > }; > static void __init yama_init_sysctl(void) >