[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/2] xen/xsm: Add new SILO mode for XSM



When SILO is enabled, there would be no page-sharing or event notifications
between unprivileged VMs (no grant tables or event channels).

Signed-off-by: Xin Li <xin.li@xxxxxxxxxx>

---
CC: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
CC: George Dunlap <George.Dunlap@xxxxxxxxxxxxx>
CC: Jan Beulich <JBeulich@xxxxxxxx>
CC: Konrad Rzeszutek Wilk <konrad.wilk@xxxxxxxxxx>
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Tim Deegan <tim@xxxxxxx>
CC: Wei Liu <wei.liu2@xxxxxxxxxx>
CC: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx>
CC: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CC: Ming Lu <ming.lu@xxxxxxxxxx>

v4:
1. include the dummy.h as a copy, and call the dummy module functions to avoid
indirect all.
2. call register_xsm() to setup silo module.

---
 docs/misc/xen-command-line.markdown |   5 +-
 xen/common/Kconfig                  |  15 ++++
 xen/include/xsm/dummy.h             |   5 ++
 xen/include/xsm/xsm.h               |   6 ++
 xen/xsm/Makefile                    |   1 +
 xen/xsm/dummy.c                     |   1 -
 xen/xsm/silo.c                      | 109 ++++++++++++++++++++++++++++
 xen/xsm/xsm_core.c                  |  11 +++
 8 files changed, 151 insertions(+), 2 deletions(-)
 create mode 100644 xen/xsm/silo.c

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index cf9924f53f..1b49fda8fc 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -900,7 +900,7 @@ Note that specifying zero as domU value means zero, while 
for dom0 it means
 to use the default.
 
 ### xsm
-> `= dummy | flask`
+> `= dummy | flask | silo`
 
 > Default: `dummy`
 
@@ -911,6 +911,9 @@ the hypervisor was compiled with XSM support.
   (the dummy module) will be applied.  it's also used when XSM is compiled out.
 * `flask`: this is the policy based access control.  To choose this, the
   separated option in kconfig must also be enabled.
+* `silo`: this will deny any unmediated communication channels between
+  unprivileged VMs.  To choose this, the separated option in kconfig must also
+  be enabled.
 
 ### flask
 > `= permissive | enforcing | late | disabled`
diff --git a/xen/common/Kconfig b/xen/common/Kconfig
index f802efb625..ce965fbf17 100644
--- a/xen/common/Kconfig
+++ b/xen/common/Kconfig
@@ -154,15 +154,30 @@ config XSM_FLASK_POLICY
 
          If unsure, say Y.
 
+config XSM_SILO
+       def_bool y
+       prompt "SILO support"
+       depends on XSM
+       ---help---
+         Enables SILO as the access control mechanism used by the XSM 
framework.
+         This is not the default module, add boot parameter xsm=silo to choose
+         it. This will deny any unmediated communication channels (grant tables
+         and event channels) between unprivileged VMs.
+
+         If unsure, say Y.
+
 choice
        prompt "Default XSM implementation"
        depends on XSM
        default XSM_FLASK_DEFAULT if XSM_FLASK
+       default XSM_SILO_DEFAULT if XSM_SILO
        default XSM_DUMMY_DEFAULT
        config XSM_DUMMY_DEFAULT
                bool "Match non-XSM behavior"
        config XSM_FLASK_DEFAULT
                bool "FLux Advanced Security Kernel" if XSM_FLASK
+       config XSM_SILO_DEFAULT
+               bool "SILO" if XSM_SILO
 endchoice
 
 config LATE_HWDOM
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index b0ac1f66b3..b2bb16c55e 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -48,7 +48,12 @@ void __xsm_action_mismatch_detected(void);
  * There is no xsm_default_t argument available, so the value from the 
assertion
  * is used to initialize the variable.
  */
+#ifdef CONFIG_XSM_SILO
+#define XSM_INLINE __attribute__ ((unused))
+#else
 #define XSM_INLINE /* */
+#endif
+
 #define XSM_DEFAULT_ARG /* */
 #define XSM_DEFAULT_VOID void
 #define XSM_ASSERT_ACTION(def) xsm_default_t action = def; (void)action
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 3d67962493..3b192b5c31 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -733,6 +733,12 @@ extern const unsigned char xsm_flask_init_policy[];
 extern const unsigned int xsm_flask_init_policy_size;
 #endif
 
+#ifdef CONFIG_XSM_SILO
+extern void silo_init(void);
+#else
+static inline void silo_init(void) {}
+#endif
+
 #else /* CONFIG_XSM */
 
 #include <xsm/dummy.h>
diff --git a/xen/xsm/Makefile b/xen/xsm/Makefile
index 8bb4a24f09..e4d581e065 100644
--- a/xen/xsm/Makefile
+++ b/xen/xsm/Makefile
@@ -1,5 +1,6 @@
 obj-y += xsm_core.o
 obj-$(CONFIG_XSM) += xsm_policy.o
 obj-$(CONFIG_XSM) += dummy.o
+obj-$(CONFIG_XSM_SILO) += silo.o
 
 subdir-$(CONFIG_XSM_FLASK) += flask
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 3290d04527..06a674fad0 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -11,7 +11,6 @@
  */
 
 #define XSM_NO_WRAPPERS
-#define XSM_INLINE /* */
 #include <xsm/dummy.h>
 
 struct xsm_operations dummy_xsm_ops;
diff --git a/xen/xsm/silo.c b/xen/xsm/silo.c
new file mode 100644
index 0000000000..d6ef6abd32
--- /dev/null
+++ b/xen/xsm/silo.c
@@ -0,0 +1,109 @@
+/******************************************************************************
+ * xsm/silo.c
+ *
+ * SILO module for XSM(Xen Security Modules)
+ *
+ * Copyright (c) 2018 Citrix Systems Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+#define XSM_NO_WRAPPERS
+
+#include <xsm/dummy.h>
+
+/*
+ * Check if inter-domain communication is allowed.
+ * Return true when pass check.
+ */
+static bool silo_mode_dom_check(const struct domain *ldom,
+                                const struct domain *rdom)
+{
+    const struct domain *cur_dom = current->domain;
+
+    return (is_control_domain(cur_dom) || is_control_domain(ldom) ||
+            is_control_domain(rdom) || ldom == rdom);
+}
+
+static int silo_evtchn_unbound(struct domain *d1, struct evtchn *chn,
+                               domid_t id2)
+{
+    int rc = -EPERM;
+    struct domain *d2 = rcu_lock_domain_by_any_id(id2);
+
+    if ( d2 == NULL )
+        rc = -ESRCH;
+    else
+    {
+        if ( silo_mode_dom_check(d1, d2) )
+            rc = xsm_evtchn_unbound(d1, chn, id2);
+        rcu_unlock_domain(d2);
+    }
+
+    return rc;
+}
+
+static int silo_evtchn_interdomain(struct domain *d1, struct evtchn *chan1,
+                                   struct domain *d2, struct evtchn *chan2)
+{
+    if ( silo_mode_dom_check(d1, d2) )
+        return xsm_evtchn_interdomain(d1, chan1, d2, chan2);
+    return -EPERM;
+}
+
+static int silo_grant_mapref(struct domain *d1, struct domain *d2,
+                             uint32_t flags)
+{
+    if ( silo_mode_dom_check(d1, d2) )
+        return xsm_grant_mapref(d1, d2, flags);
+    return -EPERM;
+}
+
+static int silo_grant_transfer(struct domain *d1, struct domain *d2)
+{
+    if ( silo_mode_dom_check(d1, d2) )
+        return xsm_grant_transfer(d1, d2);
+    return -EPERM;
+}
+
+static int silo_grant_copy(struct domain *d1, struct domain *d2)
+{
+    if ( silo_mode_dom_check(d1, d2) )
+        return xsm_grant_copy(d1, d2);
+    return -EPERM;
+}
+
+static struct xsm_operations silo_xsm_ops = {
+    .evtchn_unbound = silo_evtchn_unbound,
+    .evtchn_interdomain = silo_evtchn_interdomain,
+    .grant_mapref = silo_grant_mapref,
+    .grant_transfer = silo_grant_transfer,
+    .grant_copy = silo_grant_copy,
+};
+
+void __init silo_init(void)
+{
+    printk("Initialising XSM SILO mode\n");
+
+    if ( register_xsm(&silo_xsm_ops) )
+        panic("SILO: Unable to register with XSM\n");
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c
index df284ec463..262af5ec9b 100644
--- a/xen/xsm/xsm_core.c
+++ b/xen/xsm/xsm_core.c
@@ -34,11 +34,14 @@ struct xsm_operations *xsm_ops;
 enum xsm_bootparam {
     XSM_BOOTPARAM_DUMMY,
     XSM_BOOTPARAM_FLASK,
+    XSM_BOOTPARAM_SILO,
 };
 
 static enum xsm_bootparam __initdata xsm_bootparam =
 #ifdef CONFIG_XSM_FLASK_DEFAULT
     XSM_BOOTPARAM_FLASK;
+#elif CONFIG_XSM_SILO_DEFAULT
+    XSM_BOOTPARAM_SILO;
 #else
     XSM_BOOTPARAM_DUMMY;
 #endif
@@ -52,6 +55,10 @@ static int __init parse_xsm_param(const char *s)
 #ifdef CONFIG_XSM_FLASK
     else if ( !strcmp(s, "flask") )
         xsm_bootparam = XSM_BOOTPARAM_FLASK;
+#endif
+#ifdef CONFIG_XSM_SILO
+    else if ( !strcmp(s, "silo") )
+        xsm_bootparam = XSM_BOOTPARAM_SILO;
 #endif
     else {
         printk("XSM: can't parse boot parameter xsm=%s\n", s);
@@ -98,6 +105,10 @@ static int __init xsm_core_init(const void *policy_buffer, 
size_t policy_size)
         flask_init(policy_buffer, policy_size);
         break;
 
+    case XSM_BOOTPARAM_SILO:
+        silo_init();
+        break;
+
     default:
         printk("XSM: Invalid value for xsm= boot parameter\n");
         break;
-- 
2.18.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.