]> xenbits.xensource.com Git - people/liuw/xen.git/commitdiff
xsm, argo: XSM control for argo register
authorChristopher Clark <christopher.w.clark@gmail.com>
Wed, 6 Feb 2019 08:55:00 +0000 (09:55 +0100)
committerJan Beulich <jbeulich@suse.com>
Thu, 7 Feb 2019 13:25:39 +0000 (14:25 +0100)
XSM controls for argo ring registration with two distinct cases, where
the ring being registered is:

1) Single source:  registering a ring for communication to receive messages
                   from a specified single other domain.
   Default policy: allow.

2) Any source:     registering a ring for communication to receive messages
                   from any, or all, other domains (ie. wildcard).
   Default policy: deny, with runtime policy configuration via bootparam.

This commit modifies the signature of core XSM hook functions in order to
apply 'const' to arguments, needed in order for 'const' to be accepted in
signature of functions that invoke them.

Signed-off-by: Christopher Clark <christopher.clark6@baesystems.com>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Tested-by: Chris Patterson <pattersonc@ainfosec.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
tools/flask/policy/modules/guest_features.te
xen/common/argo.c
xen/include/xsm/dummy.h
xen/include/xsm/xsm.h
xen/xsm/dummy.c
xen/xsm/flask/hooks.c
xen/xsm/flask/include/avc.h
xen/xsm/flask/policy/access_vectors
xen/xsm/flask/policy/security_classes

index 9ac9780deda5ff1de981d9f5a8d399b61f681be8..d00769e1d21b6f94c797898005382b882782f6a3 100644 (file)
@@ -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.
index dce90ee302d2a749428853caec5dd95de70d1c6d..1a9a0e80134dd4071635a4a7976a3bf3f9200ea6 100644 (file)
@@ -26,6 +26,7 @@
 #include <xen/nospec.h>
 #include <xen/sched.h>
 #include <xen/time.h>
+#include <xsm/xsm.h>
 
 #include <public/argo.h>
 
@@ -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 )
         {
index a29d1efe9b04df63cd74c56e4ac5ccd5eeaeb4ef..9abfd69762887121d03baf7d6c4ad05f38190cb5 100644 (file)
@@ -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 <public/version.h>
 static XSM_INLINE int xsm_xen_version (XSM_DEFAULT_ARG uint32_t op)
 {
index 3b192b5c31542bfc57f5abf73ebf3ec3ce28d01b..0b4071424577feabca8c8fed8ff1a80a65d299db 100644 (file)
@@ -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
index 5701047c06fb2f797745ad2f006236d4a55432ef..ed236b09b326bfa3a8d174a84927ba00717fa9dc 100644 (file)
@@ -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
 }
index 96d31aaf08ba98440d3f6ca1a037f482aafda3e5..fcb74871d92aad5f6e17fcf9434d9ad996df4f4e 100644 (file)
 #include <objsec.h>
 #include <conditional.h>
 
-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)
index 4046516b9c32172e22e9e31cb7795302f7de92af..93386bd7a1f1c8d51e359f4affc8d47e40bcf34f 100644 (file)
@@ -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;
index 6fecfdaa8393ec9a21cb2480f5b261c860bda076..fb95c97418536619963fd340631238ed4f13b102 100644 (file)
@@ -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
+}
index cde4e1abbecaf573029b02faa68d489aba78cd69..50ecbabc5c56596c5b45f4878c4c22c8ba9026ba 100644 (file)
@@ -19,5 +19,6 @@ class event
 class grant
 class security
 class version
+class argo
 
 # FLASK