diff --git a/tools/flask/policy/modules/guest_features.te b/tools/flask/policy/modules/guest_features.te index 9ac9780ded..d00769e1d2 100644 --- a/tools/flask/policy/modules/guest_features.te +++ b/tools/flask/policy/modules/guest_features.te @@ -5,6 +5,12 @@ allow domain_type xen_t:xen tmem_op; # pmu_ctrl is for) allow domain_type xen_t:xen2 pmu_use; +# Allow all domains: +# to register single-sender (unicast) rings to partner with any domain; and +# to register any-sender (wildcard) rings that can be sent to by any domain. +allow domain_type xen_t:argo { register_any_source }; +allow domain_type domain_type:argo { register_single_source }; + # Allow guest console output to the serial console. This is used by PV Linux # and stub domains for early boot output, so don't audit even when we deny it. # Without XSM, this is enabled only if the Xen was compiled in debug mode. diff --git a/xen/common/argo.c b/xen/common/argo.c index dce90ee302..1a9a0e8013 100644 --- a/xen/common/argo.c +++ b/xen/common/argo.c @@ -26,6 +26,7 @@ #include #include #include +#include #include @@ -1652,8 +1653,10 @@ register_ring(struct domain *currd, if ( reg.partner_id == XEN_ARGO_DOMID_ANY ) { - if ( !opt_argo_mac_permissive ) - return -EPERM; + ret = opt_argo_mac_permissive ? xsm_argo_register_any_source(currd) : + -EPERM; + if ( ret ) + return ret; } else { @@ -1664,6 +1667,10 @@ register_ring(struct domain *currd, return -ESRCH; } + ret = xsm_argo_register_single_source(currd, dst_d); + if ( ret ) + goto out; + send_info = xzalloc(struct argo_send_info); if ( !send_info ) { diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index a29d1efe9b..9abfd69762 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -720,6 +720,20 @@ static XSM_INLINE int xsm_dm_op(XSM_DEFAULT_ARG struct domain *d) #endif /* CONFIG_X86 */ +#ifdef CONFIG_ARGO +static XSM_INLINE int xsm_argo_register_single_source(const struct domain *d, + const struct domain *t) +{ + return 0; +} + +static XSM_INLINE int xsm_argo_register_any_source(const struct domain *d) +{ + return 0; +} + +#endif /* CONFIG_ARGO */ + #include static XSM_INLINE int xsm_xen_version (XSM_DEFAULT_ARG uint32_t op) { diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 3b192b5c31..0b40714245 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -181,6 +181,11 @@ struct xsm_operations { #endif int (*xen_version) (uint32_t cmd); int (*domain_resource_map) (struct domain *d); +#ifdef CONFIG_ARGO + int (*argo_register_single_source) (const struct domain *d, + const struct domain *t); + int (*argo_register_any_source) (const struct domain *d); +#endif }; #ifdef CONFIG_XSM @@ -698,6 +703,20 @@ static inline int xsm_domain_resource_map(xsm_default_t def, struct domain *d) return xsm_ops->domain_resource_map(d); } +#ifdef CONFIG_ARGO +static inline int xsm_argo_register_single_source(const struct domain *d, + const struct domain *t) +{ + return xsm_ops->argo_register_single_source(d, t); +} + +static inline int xsm_argo_register_any_source(const struct domain *d) +{ + return xsm_ops->argo_register_any_source(d); +} + +#endif /* CONFIG_ARGO */ + #endif /* XSM_NO_WRAPPERS */ #ifdef CONFIG_MULTIBOOT diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c index 5701047c06..ed236b09b3 100644 --- a/xen/xsm/dummy.c +++ b/xen/xsm/dummy.c @@ -152,4 +152,8 @@ void __init xsm_fixup_ops (struct xsm_operations *ops) #endif set_to_dummy_if_null(ops, xen_version); set_to_dummy_if_null(ops, domain_resource_map); +#ifdef CONFIG_ARGO + set_to_dummy_if_null(ops, argo_register_single_source); + set_to_dummy_if_null(ops, argo_register_any_source); +#endif } diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 96d31aaf08..fcb74871d9 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -36,13 +36,14 @@ #include #include -static u32 domain_sid(struct domain *dom) +static u32 domain_sid(const struct domain *dom) { struct domain_security_struct *dsec = dom->ssid; return dsec->sid; } -static u32 domain_target_sid(struct domain *src, struct domain *dst) +static u32 domain_target_sid(const struct domain *src, + const struct domain *dst) { struct domain_security_struct *ssec = src->ssid; struct domain_security_struct *dsec = dst->ssid; @@ -58,7 +59,8 @@ static u32 evtchn_sid(const struct evtchn *chn) return chn->ssid.flask_sid; } -static int domain_has_perm(struct domain *dom1, struct domain *dom2, +static int domain_has_perm(const struct domain *dom1, + const struct domain *dom2, u16 class, u32 perms) { u32 ssid, tsid; @@ -1717,6 +1719,21 @@ static int flask_domain_resource_map(struct domain *d) return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__RESOURCE_MAP); } +#ifdef CONFIG_ARGO +static int flask_argo_register_single_source(const struct domain *d, + const struct domain *t) +{ + return domain_has_perm(d, t, SECCLASS_ARGO, + ARGO__REGISTER_SINGLE_SOURCE); +} + +static int flask_argo_register_any_source(const struct domain *d) +{ + return avc_has_perm(domain_sid(d), SECINITSID_XEN, SECCLASS_ARGO, + ARGO__REGISTER_ANY_SOURCE, NULL); +} +#endif + long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op); int compat_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op); @@ -1851,6 +1868,10 @@ static struct xsm_operations flask_ops = { #endif .xen_version = flask_xen_version, .domain_resource_map = flask_domain_resource_map, +#ifdef CONFIG_ARGO + .argo_register_single_source = flask_argo_register_single_source, + .argo_register_any_source = flask_argo_register_any_source, +#endif }; void __init flask_init(const void *policy_buffer, size_t policy_size) diff --git a/xen/xsm/flask/include/avc.h b/xen/xsm/flask/include/avc.h index 4046516b9c..93386bd7a1 100644 --- a/xen/xsm/flask/include/avc.h +++ b/xen/xsm/flask/include/avc.h @@ -40,8 +40,8 @@ struct avc_audit_data { #define AVC_AUDIT_DATA_RANGE 3 #define AVC_AUDIT_DATA_MEMORY 4 #define AVC_AUDIT_DATA_DTDEV 5 - struct domain *sdom; - struct domain *tdom; + const struct domain *sdom; + const struct domain *tdom; union { unsigned long device; int irq; diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors index 6fecfdaa83..fb95c97418 100644 --- a/xen/xsm/flask/policy/access_vectors +++ b/xen/xsm/flask/policy/access_vectors @@ -531,3 +531,14 @@ class version # Xen build id xen_build_id } + +# Class argo is used to describe the Argo interdomain communication system. +class argo +{ + # Domain requesting registration of a communication ring + # to receive messages from a specific other domain. + register_single_source + # Domain requesting registration of a communication ring + # to receive messages from any other domain. + register_any_source +} diff --git a/xen/xsm/flask/policy/security_classes b/xen/xsm/flask/policy/security_classes index cde4e1abbe..50ecbabc5c 100644 --- a/xen/xsm/flask/policy/security_classes +++ b/xen/xsm/flask/policy/security_classes @@ -19,5 +19,6 @@ class event class grant class security class version +class argo # FLASK