All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <sean.j.christopherson@intel.com>
To: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Cc: linux-sgx@vger.kernel.org, Dave Hansen <dave.hansen@intel.com>,
	Cedric Xing <cedric.xing@intel.com>,
	Andy Lutomirski <luto@kernel.org>,
	Jethro Beekman <jethro@fortanix.com>,
	"Dr . Greg Wettstein" <greg@enjellic.com>,
	Stephen Smalley <sds@tycho.nsa.gov>
Subject: [RFC PATCH v3 10/12] security/selinux: Add enclave_load() implementation
Date: Mon, 17 Jun 2019 15:24:36 -0700	[thread overview]
Message-ID: <20190617222438.2080-11-sean.j.christopherson@intel.com> (raw)
In-Reply-To: <20190617222438.2080-1-sean.j.christopherson@intel.com>

The goal of selinux_enclave_load() is to provide a facsimile of the
existing selinux_file_mprotect() and file_map_prot_check() policies,
but tailored to the unique properties of SGX.

For example, an enclave page is technically backed by a MAP_SHARED file,
but the "file" is essentially shared memory that is never persisted
anywhere and also requires execute permissions (for some pages).

Enclaves are also less priveleged than normal user code, e.g. SYSCALL
instructions #UD if attempted in an enclave.  For this reason, add SGX
specific permissions instead of reusing existing permissions such as
FILE__EXECUTE so that policies can allow running code in an enclave, or
allow dynamically loading code in an enclave without having to grant the
same capability to normal user code outside of the enclave.

Intended use of each permission:

  - SGX_EXECMOD: dynamically load code within the enclave itself
  - SGX_EXECUNMR: load unmeasured code into the enclave, e.g. Graphene
  - SGX_EXECANON: load code from anonymous memory (likely Graphene)
  - SGX_EXECUTE: load an enclave from a file, i.e. normal behavior

Note, equivalents to FILE__READ and FILE__WRITE are intentionally never
required.  Writes to the enclave page are contained to the EPC, i.e.
never hit the original file, and read permissions have already been
vetted (or the VMA doesn't have PROT_READ, in which case loading the
page into the enclave will fail).

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
---
 security/selinux/hooks.c            | 55 +++++++++++++++++++++++++++--
 security/selinux/include/classmap.h |  5 +--
 2 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 22e0f4a71333..ea452a416fe1 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -6727,6 +6727,12 @@ static void selinux_bpf_prog_free(struct bpf_prog_aux *aux)
 #endif
 
 #ifdef CONFIG_INTEL_SGX
+static inline int sgx_has_perm(u32 sid, u32 requested)
+{
+	return avc_has_perm(&selinux_state, sid, sid,
+			    SECCLASS_PROCESS2, requested, NULL);
+}
+
 static int selinux_enclave_map(unsigned long prot)
 {
 	const struct cred *cred = current_cred();
@@ -6736,11 +6742,53 @@ static int selinux_enclave_map(unsigned long prot)
 	WARN_ON_ONCE(!default_noexec);
 
 	if ((prot & PROT_EXEC) && (prot & PROT_WRITE))
-		return avc_has_perm(&selinux_state, sid, sid,
-				    SECCLASS_PROCESS2, PROCESS2__SGX_EXECMEM,
-				    NULL);
+		return sgx_has_perm(sid, PROCESS2__SGX_EXECMEM);
+
 	return 0;
 }
+
+static int selinux_enclave_load(struct vm_area_struct *vma, unsigned long prot,
+				bool measured)
+{
+	const struct cred *cred = current_cred();
+	u32 sid = cred_sid(cred);
+	int ret;
+
+	/* SGX is supported only in 64-bit kernels. */
+	WARN_ON_ONCE(!default_noexec);
+
+	/* Only executable enclave pages are restricted in any way. */
+	if (!(prot & PROT_EXEC))
+		return 0;
+
+	/*
+	 * WX at load time only requires EXECMOD, e.g. to allow W->X.  Actual
+	 * WX mappings require EXECMEM (see selinux_enclave_map()).
+	 */
+	if (prot & PROT_WRITE) {
+		ret = sgx_has_perm(sid, PROCESS2__SGX_EXECMOD);
+		if (ret)
+			goto out;
+	}
+	if (!measured) {
+		ret = sgx_has_perm(sid, PROCESS2__SGX_EXECUNMR);
+		if (ret)
+			goto out;
+	}
+
+	if (!vma->vm_file || !IS_PRIVATE(file_inode(vma->vm_file)) ||
+	    vma->anon_vma)
+		/*
+		 * Loading enclave code from an anonymous mapping or from a
+		 * modified private file mapping.
+		 */
+		ret = sgx_has_perm(sid, PROCESS2__SGX_EXECANON);
+	else
+		/* Loading from a shared or unmodified private file mapping. */
+		ret = file_has_perm(cred, vma->vm_file, FILE__SGX_EXECUTE);
+out:
+	return ret;
+}
 #endif
 
 struct lsm_blob_sizes selinux_blob_sizes __lsm_ro_after_init = {
@@ -6988,6 +7036,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
 
 #ifdef CONFIG_INTEL_SGX
 	LSM_HOOK_INIT(enclave_map, selinux_enclave_map),
+	LSM_HOOK_INIT(enclave_load, selinux_enclave_load),
 #endif
 };
 
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 0f525f5b926f..29a0a74268cd 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -52,7 +52,8 @@ struct security_class_mapping secclass_map[] = {
 	    "setsockcreate", "getrlimit", NULL } },
 	{ "process2",
 	  { "nnp_transition", "nosuid_transition",
-	    "sgx_execmem", NULL } },
+	    "sgx_execmem", "sgx_execmod", "sgx_execanon", "sgx_execunmr",
+	    NULL } },
 	{ "system",
 	  { "ipc_info", "syslog_read", "syslog_mod",
 	    "syslog_console", "module_request", "module_load", NULL } },
@@ -64,7 +65,7 @@ struct security_class_mapping secclass_map[] = {
 	    "quotaget", NULL } },
 	{ "file",
 	  { COMMON_FILE_PERMS,
-	    "execute_no_trans", "entrypoint", NULL } },
+	    "execute_no_trans", "entrypoint", "sgx_execute", NULL } },
 	{ "dir",
 	  { COMMON_FILE_PERMS, "add_name", "remove_name",
 	    "reparent", "search", "rmdir", NULL } },
-- 
2.21.0


  parent reply	other threads:[~2019-06-17 22:24 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-17 22:24 [RFC PATCH v3 00/12] security: x86/sgx: SGX vs. LSM, round 3 Sean Christopherson
2019-06-17 22:24 ` [RFC PATCH v3 01/12] x86/sgx: Add mm to enclave at mmap() Sean Christopherson
2019-06-17 22:32   ` Dave Hansen
2019-06-17 23:42   ` Andy Lutomirski
2019-06-18 14:11     ` Sean Christopherson
2019-06-18 16:06       ` Sean Christopherson
2019-06-19 12:56   ` Jarkko Sakkinen
2019-06-19 13:00     ` Jarkko Sakkinen
2019-06-20 20:09       ` Jarkko Sakkinen
2019-06-17 22:24 ` [RFC PATCH v3 02/12] x86/sgx: Do not naturally align MAP_FIXED address Sean Christopherson
2019-06-19 13:24   ` Jarkko Sakkinen
2019-06-19 14:08     ` Sean Christopherson
2019-06-20 22:07       ` Jarkko Sakkinen
2019-06-17 22:24 ` [RFC PATCH v3 03/12] selftests: x86/sgx: Mark the enclave loader as not needing an exec stack Sean Christopherson
2019-06-17 22:24 ` [RFC PATCH v3 04/12] x86/sgx: Require userspace to define enclave pages' protection bits Sean Christopherson
2019-06-19 14:43   ` Jarkko Sakkinen
2019-06-19 15:20     ` Sean Christopherson
2019-06-20 22:17       ` Jarkko Sakkinen
2019-07-07 19:08         ` Sean Christopherson
2019-07-08 15:23           ` Jarkko Sakkinen
2019-07-08 16:19             ` Sean Christopherson
2019-07-09 16:06               ` Jarkko Sakkinen
2019-07-10 17:25                 ` Sean Christopherson
2019-07-15 22:29                   ` Andy Lutomirski
2019-08-01 16:38                     ` Jarkko Sakkinen
2019-08-04 22:20                       ` Andy Lutomirski
2019-08-05 20:51                         ` Jarkko Sakkinen
2019-08-05 21:30                           ` Andy Lutomirski
2019-08-07 18:51                             ` Jarkko Sakkinen
2019-06-17 22:24 ` [RFC PATCH v3 05/12] x86/sgx: Enforce noexec filesystem restriction for enclaves Sean Christopherson
2019-06-19 14:46   ` Jarkko Sakkinen
2019-06-17 22:24 ` [RFC PATCH v3 06/12] mm: Introduce vm_ops->may_mprotect() Sean Christopherson
2019-06-17 22:24 ` [RFC PATCH v3 07/12] LSM: x86/sgx: Introduce ->enclave_map() hook for Intel SGX Sean Christopherson
2019-06-17 22:24 ` [RFC PATCH v3 08/12] security/selinux: Require SGX_EXECMEM to map enclave page WX Sean Christopherson
2019-06-17 22:24 ` [RFC PATCH v3 09/12] LSM: x86/sgx: Introduce ->enclave_load() hook for Intel SGX Sean Christopherson
2019-06-19 14:56   ` Jarkko Sakkinen
2019-06-19 21:13     ` James Morris
2019-06-20  9:28       ` Dr. Greg
2019-06-20 22:22       ` Jarkko Sakkinen
2019-06-23 17:16       ` Dr. Greg
2019-06-26 20:39         ` James Morris
2019-06-17 22:24 ` Sean Christopherson [this message]
2019-06-18 14:49   ` [RFC PATCH v3 10/12] security/selinux: Add enclave_load() implementation Stephen Smalley
2019-06-19 20:59     ` Sean Christopherson
2019-06-17 22:24 ` [RFC PATCH v3 11/12] security/apparmor: " Sean Christopherson
2019-06-17 22:24 ` [RFC PATCH v3 12/12] LSM: x86/sgx: Show line of sight to LSM support SGX2's EAUG Sean Christopherson
2019-06-18 13:38 ` [RFC PATCH v3 00/12] security: x86/sgx: SGX vs. LSM, round 3 Stephen Smalley
2019-06-18 13:55   ` Sean Christopherson
2019-06-18 15:13     ` Stephen Smalley
2019-06-25 16:29 ` Jarkko Sakkinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190617222438.2080-11-sean.j.christopherson@intel.com \
    --to=sean.j.christopherson@intel.com \
    --cc=cedric.xing@intel.com \
    --cc=dave.hansen@intel.com \
    --cc=greg@enjellic.com \
    --cc=jarkko.sakkinen@linux.intel.com \
    --cc=jethro@fortanix.com \
    --cc=linux-sgx@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=sds@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.