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@citrix.com>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Xin Li authored and Julien Grall committed 2019-06-14 14:49:19 +01:00
1 parent f092d868e9
commit 1ff6b4daf4
7 files changed
+147 -2

No files matched your search

+4 -1
View File
@@ -791,7 +791,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`
@@ -802,6 +802,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`
+15
View File
@@ -137,15 +137,30 @@ config XSM_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
+2 -1
View File
@@ -34,7 +34,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
+6
View File
@@ -742,6 +742,12 @@ extern const unsigned char xsm_init_policy[];
extern const unsigned int xsm_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>
+1
View File
@@ -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_FLASK) += flask
+108
View File
@@ -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:
*/
+11
View File
@@ -30,11 +30,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
@@ -48,6 +51,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
rc = -EINVAL;
@@ -92,6 +99,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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.