selinux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Cedric Xing <cedric.xing@intel.com>
To: linux-sgx@vger.kernel.org, linux-security-module@vger.kernel.org,
	selinux@vger.kernel.org, cedric.xing@intel.com
Subject: [RFC PATCH v3 3/4] X86/sgx: Introduce EMA as a new LSM module
Date: Sun,  7 Jul 2019 16:41:33 -0700	[thread overview]
Message-ID: <41e1a1a2f66226d88d45675434eb34dde5d0f50d.1562542383.git.cedric.xing@intel.com> (raw)
In-Reply-To: <cover.1562542383.git.cedric.xing@intel.com>
In-Reply-To: <cover.1562542383.git.cedric.xing@intel.com>

As enclave pages have different lifespan than the existing MAP_PRIVATE and
MAP_SHARED pages, a new data structure is required outside of VMA to track
their protections and/or origins. Enclave Memory Area (or EMA for short) has
been introduced to address the need. EMAs are maintained by a new LSM module
named “ema”, which is similar to the idea of the “capability” LSM module.

This new “ema” module has LSM_ORDER_FIRST so will always be dispatched before
other LSM_ORDER_MUTABLE modules (e.g. selinux, apparmor, etc.). It is
responsible for initializing EMA maps, and inserting and freeing EMA nodes, and
offers APIs for other LSM modules to query/update EMAs. Details could be found
in include/linux/lsm_ema.h and security/commonema.c.

Signed-off-by: Cedric Xing <cedric.xing@intel.com>
---
 include/linux/lsm_ema.h |  97 ++++++++++++++
 security/Makefile       |   1 +
 security/commonema.c    | 277 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 375 insertions(+)
 create mode 100644 include/linux/lsm_ema.h
 create mode 100644 security/commonema.c

diff --git a/include/linux/lsm_ema.h b/include/linux/lsm_ema.h
new file mode 100644
index 000000000000..59fc4ea6fa78
--- /dev/null
+++ b/include/linux/lsm_ema.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
+/**
+ * Enclave Memory Area interface for LSM modules
+ *
+ * Copyright(c) 2016-19 Intel Corporation.
+ */
+
+#ifndef _LSM_EMA_H_
+#define _LSM_EMA_H_
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+
+/**
+ * ema - Enclave Memory Area structure for LSM modules
+ *
+ * Data structure to track origins of enclave pages
+ *
+ * @link:
+ *	Link to adjacent EMAs. EMAs are sorted by their addresses in ascending
+ *	order
+ * @start:
+ *	Starting address
+ * @end:
+ *	Ending address
+ * @source:
+ *	File from which this range was loaded from, or NULL if not loaded from
+ *	any files
+ */
+struct ema {
+	struct list_head	link;
+	size_t			start;
+	size_t			end;
+	struct file		*source;
+};
+
+#define ema_data(ema, offset)	\
+	((void *)((char *)((struct ema *)(ema) + 1) + offset))
+
+/**
+ * ema_map - LSM Enclave Memory Map structure for LSM modules
+ *
+ * Container for EMAs of an enclave
+ *
+ * @list:
+ *	Head of a list of sorted EMAs
+ * @lock:
+ *	Acquire before querying/updateing the list EMAs
+ */
+struct ema_map {
+	struct list_head	list;
+	struct mutex		lock;
+};
+
+size_t __init ema_request_blob(size_t blob_size);
+struct ema_map *ema_get_map(struct file *encl);
+int ema_apply_to_range(struct ema_map *map, size_t start, size_t end,
+		       int (*cb)(struct ema *ema, void *arg), void *arg);
+void ema_remove_range(struct ema_map *map, size_t start, size_t end);
+
+static inline int __must_check ema_lock_map(struct ema_map *map)
+{
+	return mutex_lock_interruptible(&map->lock);
+}
+
+static inline void ema_unlock_map(struct ema_map *map)
+{
+	mutex_unlock(&map->lock);
+}
+
+static inline int ema_lock_apply_to_range(struct ema_map *map,
+					  size_t start, size_t end,
+					  int (*cb)(struct ema *, void *),
+					  void *arg)
+{
+	int rc = ema_lock_map(map);
+	if (!rc) {
+		rc = ema_apply_to_range(map, start, end, cb, arg);
+		ema_unlock_map(map);
+	}
+	return rc;
+}
+
+static inline int ema_lock_remove_range(struct ema_map *map,
+					size_t start, size_t end)
+{
+	int rc = ema_lock_map(map);
+	if (!rc) {
+		ema_remove_range(map, start, end);
+		ema_unlock_map(map);
+	}
+	return rc;
+}
+
+#endif /* _LSM_EMA_H_ */
diff --git a/security/Makefile b/security/Makefile
index c598b904938f..b66d03a94853 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -28,6 +28,7 @@ obj-$(CONFIG_SECURITY_YAMA)		+= yama/
 obj-$(CONFIG_SECURITY_LOADPIN)		+= loadpin/
 obj-$(CONFIG_SECURITY_SAFESETID)       += safesetid/
 obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
+obj-$(CONFIG_INTEL_SGX)			+= commonema.o
 
 # Object integrity file lists
 subdir-$(CONFIG_INTEGRITY)		+= integrity
diff --git a/security/commonema.c b/security/commonema.c
new file mode 100644
index 000000000000..c5b0bdfdc013
--- /dev/null
+++ b/security/commonema.c
@@ -0,0 +1,277 @@
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
+// Copyright(c) 2016-18 Intel Corporation.
+
+#include <linux/lsm_ema.h>
+#include <linux/lsm_hooks.h>
+#include <linux/slab.h>
+
+static struct kmem_cache *_map_cache;
+static struct kmem_cache *_node_cache;
+static size_t _data_size __lsm_ro_after_init;
+
+static struct lsm_blob_sizes ema_blob_sizes __lsm_ro_after_init = {
+	.lbs_file = sizeof(atomic_long_t),
+};
+
+static atomic_long_t *_map_file(struct file *encl)
+{
+	return (void *)((char *)(encl->f_security) + ema_blob_sizes.lbs_file);
+}
+
+static struct ema_map *_alloc_map(void)
+{
+	struct ema_map *m;
+
+	m = kmem_cache_zalloc(_map_cache, GFP_KERNEL);
+	if (likely(m)) {
+		INIT_LIST_HEAD(&m->list);
+		mutex_init(&m->lock);
+	}
+	return m;
+}
+
+static struct ema *_new_ema(size_t start, size_t end, struct file *src)
+{
+	struct ema *ema;
+
+	if (unlikely(!_node_cache)) {
+		struct kmem_cache *c;
+
+		c = kmem_cache_create("lsm-ema", sizeof(*ema) + _data_size,
+				      __alignof__(typeof(*ema)), SLAB_PANIC,
+				      NULL);
+		if (atomic_long_cmpxchg((atomic_long_t *)&_node_cache, 0,
+					(long)c))
+			kmem_cache_destroy(c);
+	}
+
+	ema = kmem_cache_zalloc(_node_cache, GFP_KERNEL);
+	if (likely(ema)) {
+		INIT_LIST_HEAD(&ema->link);
+		ema->start = start;
+		ema->end = end;
+		if (src)
+			ema->source = get_file(src);
+	}
+	return ema;
+}
+
+static void _free_ema(struct ema *ema)
+{
+	if (ema->source)
+		fput(ema->source);
+	kmem_cache_free(_node_cache, ema);
+}
+
+static void _free_map(struct ema_map *map)
+{
+	struct ema *p, *n;
+
+	WARN_ON(mutex_is_locked(&map->lock));
+	list_for_each_entry_safe(p, n, &map->list, link)
+		_free_ema(p);
+	kmem_cache_free(_map_cache, map);
+}
+
+static struct ema_map *_init_map(struct file *encl)
+{
+	struct ema_map *m = ema_get_map(encl);
+	if (!m) {
+		m = _alloc_map();
+		if (atomic_long_cmpxchg(_map_file(encl), 0, (long)m)) {
+			_free_map(m);
+			m = ema_get_map(encl);
+		}
+	}
+	return m;
+}
+
+static inline struct ema *_next_ema(struct ema *p, struct ema_map *map)
+{
+	p = list_next_entry(p, link);
+	return &p->link == &map->list ? NULL : p;
+}
+
+static inline struct ema *_find_ema(struct ema_map *map, size_t a)
+{
+	struct ema *p;
+
+	WARN_ON(!mutex_is_locked(&map->lock));
+
+	list_for_each_entry(p, &map->list, link)
+		if (a < p->end)
+			break;
+	return &p->link == &map->list ? NULL : p;
+}
+
+static struct ema *_split_ema(struct ema *p, size_t at)
+{
+	typeof(p) n;
+
+	if (at <= p->start || at >= p->end)
+		return p;
+
+	n = _new_ema(p->start, at, p->source);
+	if (likely(n)) {
+		memcpy(n + 1, p + 1, _data_size);
+		p->start = at;
+		list_add_tail(&n->link, &p->link);
+	}
+	return n;
+}
+
+static int _merge_ema(struct ema *p, struct ema_map *map)
+{
+	typeof(p) prev = list_prev_entry(p, link);
+
+	WARN_ON(!mutex_is_locked(&map->lock));
+
+	if (&prev->link == &map->list || prev->end != p->start ||
+	    prev->source != p->source || memcmp(prev + 1, p + 1, _data_size))
+		return 0;
+
+	p->start = prev->start;
+	fput(prev->source);
+	_free_ema(prev);
+	return 1;
+}
+
+static inline int _insert_ema(struct ema_map *map, struct ema *n)
+{
+	typeof(n) p = _find_ema(map, n->start);
+
+	if (!p)
+		list_add_tail(&n->link, &map->list);
+	else if (n->end <= p->start)
+		list_add_tail(&n->link, &p->link);
+	else
+		return -EEXIST;
+
+	_merge_ema(n, map);
+	if (p)
+		_merge_ema(p, map);
+	return 0;
+}
+
+static void ema_file_free_security(struct file *encl)
+{
+	struct ema_map *m = ema_get_map(encl);
+	if (m)
+		_free_map(m);
+}
+
+static int ema_enclave_load(struct file *encl, size_t start, size_t end,
+			    size_t flags, struct vm_area_struct *vma)
+{
+	struct ema_map *m;
+	struct ema *ema;
+	int rc;
+
+	m = _init_map(encl);
+	if (unlikely(!m))
+		return -ENOMEM;
+
+	ema = _new_ema(start, end, vma ? vma->vm_file : NULL);
+	if (unlikely(!ema))
+		return -ENOMEM;
+
+	rc = ema_lock_map(m);
+	if (!rc) {
+		rc = _insert_ema(m, ema);
+		ema_unlock_map(m);
+	}
+	if (rc)
+		_free_ema(ema);
+	return rc;
+}
+
+static int ema_enclave_init(struct file *encl, struct sgx_sigstruct *sigstruct,
+			    struct vm_area_struct *vma)
+{
+	if (unlikely(!_init_map(encl)))
+		return -ENOMEM;
+	return 0;
+}
+
+static struct security_hook_list ema_hooks[] __lsm_ro_after_init = {
+	LSM_HOOK_INIT(file_free_security, ema_file_free_security),
+	LSM_HOOK_INIT(enclave_load, ema_enclave_load),
+	LSM_HOOK_INIT(enclave_init, ema_enclave_init),
+};
+
+static int __init ema_init(void)
+{
+	_map_cache = kmem_cache_create("lsm-ema_map", sizeof(struct ema_map),
+				       __alignof__(struct ema_map), SLAB_PANIC,
+				       NULL);
+	security_add_hooks(ema_hooks, ARRAY_SIZE(ema_hooks), "ema");
+	return 0;
+}
+
+DEFINE_LSM(ema) = {
+	.name = "ema",
+	.order = LSM_ORDER_FIRST,
+	.init = ema_init,
+	.blobs = &ema_blob_sizes,
+};
+
+/* ema_request_blob shall only be called from LSM module init function */
+size_t __init ema_request_blob(size_t size)
+{
+	typeof(_data_size) offset = _data_size;
+	_data_size += size;
+	return offset;
+}
+
+struct ema_map *ema_get_map(struct file *encl)
+{
+	return (struct ema_map *)atomic_long_read(_map_file(encl));
+}
+
+/**
+ * Invoke a callback function on every EMA falls within range, split EMAs as
+ * needed
+ */
+int ema_apply_to_range(struct ema_map *map, size_t start, size_t end,
+		       int (*cb)(struct ema *, void *), void *arg)
+{
+	struct ema *ema;
+	int rc;
+
+	ema = _find_ema(map, start);
+	while (ema && end > ema->start) {
+		if (start > ema->start)
+			_split_ema(ema, start);
+		if (end < ema->end)
+			ema = _split_ema(ema, end);
+
+		rc = (*cb)(ema, arg);
+		_merge_ema(ema, map);
+		if (rc)
+			return rc;
+
+		ema = _next_ema(ema, map);
+	}
+
+	if (ema)
+		_merge_ema(ema, map);
+	return 0;
+}
+
+/* Remove all EMAs falling within range, split EMAs as needed */
+void ema_remove_range(struct ema_map *map, size_t start, size_t end)
+{
+	struct ema *ema, *n;
+
+	ema = _find_ema(map, start);
+	while (ema && end > ema->start) {
+		if (start > ema->start)
+			_split_ema(ema, start);
+		if (end < ema->end)
+			ema = _split_ema(ema, end);
+
+		n = _next_ema(ema, map);
+		_free_ema(ema);
+		ema = n;
+	}
+}
-- 
2.17.1


  parent reply	other threads:[~2019-07-07 23:41 UTC|newest]

Thread overview: 156+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-19 22:23 [RFC PATCH v4 00/12] security: x86/sgx: SGX vs. LSM Sean Christopherson
2019-06-19 22:23 ` [RFC PATCH v4 01/12] x86/sgx: Use mmu_notifier.release() instead of per-vma refcounting Sean Christopherson
2019-06-20 21:03   ` Jarkko Sakkinen
2019-07-08 14:57     ` Sean Christopherson
2019-07-09 16:18       ` Jarkko Sakkinen
2019-06-19 22:23 ` [RFC PATCH v4 02/12] x86/sgx: Do not naturally align MAP_FIXED address Sean Christopherson
2019-06-20 21:09   ` Jarkko Sakkinen
2019-06-20 22:09     ` Jarkko Sakkinen
2019-06-19 22:23 ` [RFC PATCH v4 03/12] selftests: x86/sgx: Mark the enclave loader as not needing an exec stack Sean Christopherson
2019-06-20 21:17   ` Jarkko Sakkinen
2019-06-19 22:23 ` [RFC PATCH v4 04/12] x86/sgx: Require userspace to define enclave pages' protection bits Sean Christopherson
2019-06-21  1:07   ` Jarkko Sakkinen
2019-06-21  1:16     ` Jarkko Sakkinen
2019-06-21 16:42   ` Xing, Cedric
2019-07-08 16:34     ` Sean Christopherson
2019-07-08 17:29       ` Xing, Cedric
2019-07-01 18:00   ` Andy Lutomirski
2019-07-01 19:22     ` Xing, Cedric
2019-06-19 22:23 ` [RFC PATCH v4 05/12] x86/sgx: Enforce noexec filesystem restriction for enclaves Sean Christopherson
2019-06-21  1:26   ` Jarkko Sakkinen
2019-07-07 19:03     ` Sean Christopherson
2019-06-19 22:23 ` [RFC PATCH v4 06/12] mm: Introduce vm_ops->may_mprotect() Sean Christopherson
2019-06-21  1:35   ` Jarkko Sakkinen
2019-06-19 22:23 ` [RFC PATCH v4 07/12] LSM: x86/sgx: Introduce ->enclave_map() hook for Intel SGX Sean Christopherson
2019-06-21  2:28   ` Jarkko Sakkinen
2019-06-21 16:54   ` Xing, Cedric
2019-06-25 20:48     ` Stephen Smalley
2019-06-27 20:29       ` Xing, Cedric
2019-07-07 18:01         ` Sean Christopherson
2019-06-19 22:23 ` [RFC PATCH v4 08/12] security/selinux: Require SGX_MAPWX to map enclave page WX Sean Christopherson
2019-06-21 17:09   ` Xing, Cedric
2019-06-25 21:05     ` Stephen Smalley
2019-06-27 20:26       ` Xing, Cedric
2019-06-25 20:19   ` Stephen Smalley
2019-06-26 12:49     ` Dr. Greg
2019-06-19 22:23 ` [RFC PATCH v4 09/12] LSM: x86/sgx: Introduce ->enclave_load() hook for Intel SGX Sean Christopherson
2019-06-21 17:05   ` Xing, Cedric
2019-06-25 21:01     ` Stephen Smalley
2019-06-25 21:49       ` Stephen Smalley
2019-06-27 19:38         ` Xing, Cedric
2019-06-19 22:23 ` [RFC PATCH v4 10/12] security/selinux: Add enclave_load() implementation Sean Christopherson
2019-06-21 21:22   ` Xing, Cedric
2019-06-25 21:09     ` Stephen Smalley
2019-06-27 20:19       ` Xing, Cedric
2019-06-28 16:16         ` Stephen Smalley
2019-06-28 21:20           ` Xing, Cedric
2019-06-29  1:15             ` Stephen Smalley
2019-07-01 18:14               ` Xing, Cedric
2019-06-29 23:41       ` Andy Lutomirski
2019-07-01 17:46         ` Xing, Cedric
2019-07-01 17:53           ` Andy Lutomirski
2019-07-01 18:54             ` Xing, Cedric
2019-07-01 19:03               ` Xing, Cedric
2019-07-01 19:32               ` Andy Lutomirski
2019-07-01 20:03                 ` Xing, Cedric
2019-07-07 18:46                   ` Sean Christopherson
2019-06-25 20:34   ` Stephen Smalley
2019-06-19 22:24 ` [RFC PATCH v4 11/12] security/apparmor: " Sean Christopherson
2019-06-19 22:24 ` [RFC PATCH v4 12/12] LSM: x86/sgx: Show line of sight to LSM support SGX2's EAUG Sean Christopherson
2019-06-21 17:18   ` Xing, Cedric
2019-07-08 14:34     ` Sean Christopherson
2019-06-21  1:32 ` [RFC PATCH v4 00/12] security: x86/sgx: SGX vs. LSM Jarkko Sakkinen
2019-06-27 18:56 ` [RFC PATCH v2 0/3] security/x86/sgx: SGX specific LSM hooks Cedric Xing
2019-07-03 23:16   ` Jarkko Sakkinen
2019-07-03 23:22     ` Jarkko Sakkinen
2019-07-03 23:23       ` Jarkko Sakkinen
2019-07-06  5:04     ` Xing, Cedric
2019-07-08 14:46       ` Jarkko Sakkinen
2019-07-07 23:41   ` [RFC PATCH v3 0/4] " Cedric Xing
2019-07-08 15:55     ` Sean Christopherson
2019-07-08 17:49       ` Xing, Cedric
2019-07-08 18:49         ` Sean Christopherson
2019-07-08 22:26           ` Xing, Cedric
2019-07-07 23:41   ` [RFC PATCH v3 1/4] x86/sgx: Add " Cedric Xing
2019-07-07 23:41   ` [RFC PATCH v3 2/4] x86/64: Call LSM hooks from SGX subsystem/module Cedric Xing
2019-07-09  1:03     ` Sean Christopherson
2019-07-07 23:41   ` Cedric Xing [this message]
2019-07-08 16:26     ` [RFC PATCH v3 3/4] X86/sgx: Introduce EMA as a new LSM module Casey Schaufler
2019-07-08 17:16       ` Xing, Cedric
2019-07-08 23:53         ` Casey Schaufler
2019-07-09 22:13           ` Xing, Cedric
2019-07-10  0:10             ` Casey Schaufler
2019-07-10  0:55               ` Xing, Cedric
2019-07-10 21:14                 ` Casey Schaufler
2019-07-11 13:51                 ` Stephen Smalley
2019-07-11 15:12                   ` Sean Christopherson
2019-07-11 16:11                     ` Stephen Smalley
2019-07-11 16:25                       ` Sean Christopherson
2019-07-11 16:32                         ` Stephen Smalley
2019-07-11 23:41                           ` Xing, Cedric
2019-07-07 23:41   ` [RFC PATCH v3 4/4] x86/sgx: Implement SGX specific hooks in SELinux Cedric Xing
2019-07-09  1:33     ` Sean Christopherson
2019-07-09 21:26       ` Xing, Cedric
2019-07-10 15:49     ` Sean Christopherson
2019-07-10 16:08       ` Jethro Beekman
2019-07-10 18:16         ` Xing, Cedric
2019-07-10 17:54       ` Xing, Cedric
2019-06-27 18:56 ` [RFC PATCH v2 1/3] x86/sgx: Add SGX specific LSM hooks Cedric Xing
2019-06-27 22:06   ` Casey Schaufler
2019-06-27 22:52     ` Xing, Cedric
2019-06-27 23:37       ` Casey Schaufler
2019-06-28  0:47         ` Xing, Cedric
2019-06-28 17:22           ` Casey Schaufler
2019-06-28 22:29             ` Xing, Cedric
2019-06-29  1:37             ` Stephen Smalley
2019-06-29 21:35               ` Casey Schaufler
2019-07-01 17:57                 ` Xing, Cedric
2019-07-01 19:53                   ` Casey Schaufler
2019-07-01 21:45                     ` Xing, Cedric
2019-07-01 23:11                       ` Casey Schaufler
2019-07-02  7:42                         ` Xing, Cedric
2019-07-02 15:44                           ` Casey Schaufler
2019-07-03  9:46                             ` Dr. Greg
2019-07-03 15:32                               ` Casey Schaufler
2019-07-07 13:30                                 ` Dr. Greg
2019-07-09  0:02                                   ` Casey Schaufler
2019-07-09  1:52                                     ` Sean Christopherson
2019-07-09 21:16                                       ` Xing, Cedric
2019-07-11 10:22                                     ` Dr. Greg
2019-07-15 22:23                                       ` Andy Lutomirski
2019-06-28 16:37   ` Stephen Smalley
2019-06-28 21:53     ` Xing, Cedric
2019-06-29  1:22       ` Stephen Smalley
2019-07-01 18:02         ` Xing, Cedric
2019-06-29 23:46   ` Andy Lutomirski
2019-07-01 17:11     ` Xing, Cedric
2019-07-01 17:58       ` Andy Lutomirski
2019-07-01 18:31         ` Xing, Cedric
2019-07-01 19:36           ` Andy Lutomirski
2019-07-01 19:56             ` Xing, Cedric
2019-07-02  2:29               ` Andy Lutomirski
2019-07-02  6:35                 ` Xing, Cedric
2019-06-27 18:56 ` [RFC PATCH v2 2/3] x86/sgx: Call LSM hooks from SGX subsystem/module Cedric Xing
2019-06-27 18:56 ` [RFC PATCH v2 3/3] x86/sgx: Implement SGX specific hooks in SELinux Cedric Xing
2019-07-05 16:05 ` [RFC PATCH v4 00/12] security: x86/sgx: SGX vs. LSM Jarkko Sakkinen
2019-07-08 17:29   ` Sean Christopherson
2019-07-08 17:33     ` Xing, Cedric
2019-07-09 16:22     ` Jarkko Sakkinen
2019-07-09 17:09       ` Sean Christopherson
2019-07-09 20:41         ` Xing, Cedric
2019-07-09 22:25           ` Sean Christopherson
2019-07-09 23:11             ` Xing, Cedric
2019-07-10 16:57               ` Sean Christopherson
2019-07-10 20:19         ` Jarkko Sakkinen
2019-07-10 20:31           ` Sean Christopherson
2019-07-11  9:06             ` Jarkko Sakkinen
2019-07-10 22:00           ` Jarkko Sakkinen
2019-07-10 22:16         ` Jarkko Sakkinen
2019-07-10 23:16           ` Xing, Cedric
2019-07-11  9:26             ` Jarkko Sakkinen
2019-07-11 14:32               ` Stephen Smalley
2019-07-11 17:51                 ` Jarkko Sakkinen
2019-07-12  0:08                   ` Xing, Cedric
2019-07-10  1:28     ` Dr. Greg
2019-07-10  2:04       ` Xing, Cedric
2019-07-10  3:21     ` Jethro Beekman

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=41e1a1a2f66226d88d45675434eb34dde5d0f50d.1562542383.git.cedric.xing@intel.com \
    --to=cedric.xing@intel.com \
    --cc=linux-security-module@vger.kernel.org \
    --cc=linux-sgx@vger.kernel.org \
    --cc=selinux@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).