p***@xen.org
2018-11-04 04:55:54 UTC
commit 9acb115f744a73bc69bb3980e10e07b5283e0925
Author: Xin Li <***@gmail.com>
AuthorDate: Tue Oct 9 17:33:20 2018 +0800
Commit: Andrew Cooper <***@citrix.com>
CommitDate: Mon Oct 15 14:34:53 2018 +0100
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 <***@citrix.com>
Acked-by: Daniel De Graaf <***@tycho.nsa.gov>
Acked-by: Andrew Cooper <***@citrix.com>
---
docs/misc/xen-command-line.markdown | 5 +-
xen/common/Kconfig | 15 +++++
xen/include/xsm/dummy.h | 3 +-
xen/include/xsm/xsm.h | 6 ++
xen/xsm/Makefile | 1 +
xen/xsm/silo.c | 108 ++++++++++++++++++++++++++++++++++++
xen/xsm/xsm_core.c | 11 ++++
7 files changed, 147 insertions(+), 2 deletions(-)
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 67e062ecd7..2c7046eb86 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`
(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
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..ae971822d5 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -48,7 +48,8 @@ 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.
*/
-#define XSM_INLINE /* */
+#define XSM_INLINE __maybe_unused
+
#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/silo.c b/xen/xsm/silo.c
new file mode 100644
index 0000000000..4850756a3d
--- /dev/null
+++ b/xen/xsm/silo.c
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * 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 *currd = current->domain;
+
+ return (is_control_domain(currd) || 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 02404b1d1a..201c354390 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
@@ -53,6 +56,10 @@ static int __init parse_xsm_param(const char *s)
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
rc = -EINVAL;
@@ -96,6 +103,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:
ASSERT_UNREACHABLE();
break;
--
generated by git-patchbot for /home/xen/git/xen.git#master
Author: Xin Li <***@gmail.com>
AuthorDate: Tue Oct 9 17:33:20 2018 +0800
Commit: Andrew Cooper <***@citrix.com>
CommitDate: Mon Oct 15 14:34:53 2018 +0100
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 <***@citrix.com>
Acked-by: Daniel De Graaf <***@tycho.nsa.gov>
Acked-by: Andrew Cooper <***@citrix.com>
---
docs/misc/xen-command-line.markdown | 5 +-
xen/common/Kconfig | 15 +++++
xen/include/xsm/dummy.h | 3 +-
xen/include/xsm/xsm.h | 6 ++
xen/xsm/Makefile | 1 +
xen/xsm/silo.c | 108 ++++++++++++++++++++++++++++++++++++
xen/xsm/xsm_core.c | 11 ++++
7 files changed, 147 insertions(+), 2 deletions(-)
diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown
index 67e062ecd7..2c7046eb86 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/Kconfigindex 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..ae971822d5 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -48,7 +48,8 @@ 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.
*/
-#define XSM_INLINE /* */
+#define XSM_INLINE __maybe_unused
+
#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/silo.c b/xen/xsm/silo.c
new file mode 100644
index 0000000000..4850756a3d
--- /dev/null
+++ b/xen/xsm/silo.c
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * 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 *currd = current->domain;
+
+ return (is_control_domain(currd) || 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 02404b1d1a..201c354390 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
@@ -53,6 +56,10 @@ static int __init parse_xsm_param(const char *s)
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
rc = -EINVAL;
@@ -96,6 +103,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:
ASSERT_UNREACHABLE();
break;
--
generated by git-patchbot for /home/xen/git/xen.git#master