mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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:
1 parent
f092d868e9
commit
1ff6b4daf4
7 files changed
+147
-2
No files matched your search
@@ -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`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
@@ -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:
|
||||
*/
|
||||
@@ -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;
|
||||
|
||||