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
next prev 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).