All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christopher Clark <christopher.w.clark@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: "Juergen Gross" <jgross@suse.com>, "Wei Liu" <wl@xen.org>,
	"Andrew Cooper" <andrew.cooper3@citrix.com>,
	"Ian Jackson" <ian.jackson@eu.citrix.com>,
	"Rich Persaud" <persaur@gmail.com>,
	"Jan Beulich" <jbeulich@suse.com>,
	"Daniel De Graaf" <dgdegra@tycho.nsa.gov>,
	"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [Xen-devel] [RFC 4/9] XSM: Add hook for nested xen version op; revises non-nested version op
Date: Wed, 19 Jun 2019 17:30:48 -0700	[thread overview]
Message-ID: <20190620003053.21993-5-christopher.w.clark@gmail.com> (raw)
In-Reply-To: <20190620003053.21993-1-christopher.w.clark@gmail.com>

Expand XSM control to the full set of Xen version ops, to allow for
granular control over ops a domain is allowed to issue for the nested case.

Applies const to args of xsm_default_action.

Signed-off-by: Christopher Clark <christopher.clark@starlab.io>
---
 tools/flask/policy/modules/dom0.te           |  7 ++-
 tools/flask/policy/modules/guest_features.te |  5 +-
 tools/flask/policy/modules/xen.te            |  3 ++
 tools/flask/policy/policy/initial_sids       |  3 ++
 xen/arch/x86/guest/xen-nested.c              |  6 +--
 xen/include/xsm/dummy.h                      | 12 ++++-
 xen/include/xsm/xsm.h                        | 13 ++++++
 xen/xsm/dummy.c                              |  3 ++
 xen/xsm/flask/hooks.c                        | 49 ++++++++++++++------
 xen/xsm/flask/policy/access_vectors          |  6 +++
 xen/xsm/flask/policy/initial_sids            |  1 +
 11 files changed, 86 insertions(+), 22 deletions(-)

diff --git a/tools/flask/policy/modules/dom0.te b/tools/flask/policy/modules/dom0.te
index 9970f9dc08..9ed7ccb57b 100644
--- a/tools/flask/policy/modules/dom0.te
+++ b/tools/flask/policy/modules/dom0.te
@@ -22,9 +22,9 @@ allow dom0_t xen_t:xen2 {
 # Allow dom0 to use all XENVER_ subops that have checks.
 # Note that dom0 is part of domain_type so this has duplicates.
 allow dom0_t xen_t:version {
-	xen_extraversion xen_compile_info xen_capabilities
+	xen_version xen_extraversion xen_compile_info xen_capabilities
 	xen_changeset xen_pagesize xen_guest_handle xen_commandline
-	xen_build_id
+	xen_build_id xen_get_features xen_platform_parameters
 };
 
 allow dom0_t xen_t:mmu memorymap;
@@ -43,6 +43,9 @@ allow dom0_t dom0_t:domain2 {
 };
 allow dom0_t dom0_t:resource { add remove };
 
+# Allow dom0 to communicate with a nested Xen hypervisor
+allow dom0_t nestedxen_t:version { xen_version xen_get_features };
+
 # These permissions allow using the FLASK security server to compute access
 # checks locally, which could be used by a domain or service (such as xenstore)
 # that does not have its own security server to make access decisions based on
diff --git a/tools/flask/policy/modules/guest_features.te b/tools/flask/policy/modules/guest_features.te
index 2797a22761..baade15f2e 100644
--- a/tools/flask/policy/modules/guest_features.te
+++ b/tools/flask/policy/modules/guest_features.te
@@ -21,8 +21,9 @@ if (guest_writeconsole) {
 
 # For normal guests, allow all queries except XENVER_commandline.
 allow domain_type xen_t:version {
-    xen_extraversion xen_compile_info xen_capabilities
-    xen_changeset xen_pagesize xen_guest_handle
+    xen_version xen_extraversion xen_compile_info xen_capabilities
+    xen_changeset xen_pagesize xen_guest_handle xen_get_features
+    xen_platform_parameters
 };
 
 # Version queries don't need auditing when denied.  They can be
diff --git a/tools/flask/policy/modules/xen.te b/tools/flask/policy/modules/xen.te
index 3dbf93d2b8..fbd82334fd 100644
--- a/tools/flask/policy/modules/xen.te
+++ b/tools/flask/policy/modules/xen.te
@@ -26,6 +26,9 @@ attribute mls_priv;
 # The hypervisor itself
 type xen_t, xen_type, mls_priv;
 
+# A nested Xen hypervisor, if any
+type nestedxen_t, xen_type;
+
 # Domain 0
 declare_singleton_domain(dom0_t, mls_priv);
 
diff --git a/tools/flask/policy/policy/initial_sids b/tools/flask/policy/policy/initial_sids
index 6b7b7eff21..50b648df3b 100644
--- a/tools/flask/policy/policy/initial_sids
+++ b/tools/flask/policy/policy/initial_sids
@@ -16,3 +16,6 @@ sid device gen_context(system_u:object_r:device_t,s0)
 # Initial SIDs used by the toolstack for domains without defined labels
 sid domU gen_context(system_u:system_r:domU_t,s0)
 sid domDM gen_context(system_u:system_r:dm_dom_t,s0)
+
+# Initial SID for nested Xen on Xen
+sid nestedxen gen_context(system_u:system_r:nestedxen_t,s0)
diff --git a/xen/arch/x86/guest/xen-nested.c b/xen/arch/x86/guest/xen-nested.c
index 744592aa0c..fcfa5e1087 100644
--- a/xen/arch/x86/guest/xen-nested.c
+++ b/xen/arch/x86/guest/xen-nested.c
@@ -47,9 +47,9 @@ long do_nested_xen_version(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
     if ( !xen_nested )
         return -ENOSYS;
 
-    /* FIXME: apply XSM check here */
-    if ( !is_control_domain(current->domain) )
-        return -EPERM;
+    ret = xsm_nested_xen_version(XSM_PRIV, current->domain, cmd);
+    if ( ret )
+        return ret;
 
     gprintk(XENLOG_DEBUG, "Nested xen_version: %d.\n", cmd);
 
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index 01d2814fed..8011bf2cb4 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -69,7 +69,7 @@ void __xsm_action_mismatch_detected(void);
 #endif /* CONFIG_XSM */
 
 static always_inline int xsm_default_action(
-    xsm_default_t action, struct domain *src, struct domain *target)
+    xsm_default_t action, const struct domain *src, const struct domain *target)
 {
     switch ( action ) {
     case XSM_HOOK:
@@ -739,6 +739,16 @@ static XSM_INLINE int xsm_argo_send(const struct domain *d,
 
 #endif /* CONFIG_ARGO */
 
+#ifdef CONFIG_XEN_NESTED
+static XSM_INLINE int xsm_nested_xen_version(XSM_DEFAULT_ARG
+                                             const struct domain *d,
+                                             unsigned int cmd)
+{
+    XSM_ASSERT_ACTION(XSM_PRIV);
+    return xsm_default_action(action, d, NULL);
+}
+#endif
+
 #include <public/version.h>
 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 b6141f6ab1..96044cb55a 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -187,6 +187,9 @@ struct xsm_operations {
     int (*argo_register_any_source) (const struct domain *d);
     int (*argo_send) (const struct domain *d, const struct domain *t);
 #endif
+#ifdef CONFIG_XEN_NESTED
+    int (*nested_xen_version) (const struct domain *d, unsigned int cmd);
+#endif
 };
 
 #ifdef CONFIG_XSM
@@ -723,6 +726,16 @@ static inline int xsm_argo_send(const struct domain *d, const struct domain *t)
 
 #endif /* CONFIG_ARGO */
 
+#ifdef CONFIG_XEN_NESTED
+static inline int xsm_nested_xen_version(xsm_default_t def,
+                                         const struct domain *d,
+                                         unsigned int cmd)
+{
+    return xsm_ops->nested_xen_version(d, cmd);
+}
+
+#endif /* CONFIG_XEN_NESTED */
+
 #endif /* XSM_NO_WRAPPERS */
 
 #ifdef CONFIG_MULTIBOOT
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index c9a566f2b5..ed0a4b0691 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -157,4 +157,7 @@ void __init xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, argo_register_any_source);
     set_to_dummy_if_null(ops, argo_send);
 #endif
+#ifdef CONFIG_XEN_NESTED
+    set_to_dummy_if_null(ops, nested_xen_version);
+#endif
 }
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index a7d690ac3c..2835279fe7 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1666,46 +1666,56 @@ static int flask_dm_op(struct domain *d)
 
 #endif /* CONFIG_X86 */
 
-static int flask_xen_version (uint32_t op)
+static int domain_has_xen_version (const struct domain *d, u32 tsid,
+                                   uint32_t op)
 {
-    u32 dsid = domain_sid(current->domain);
+    u32 dsid = domain_sid(d);
 
     switch ( op )
     {
     case XENVER_version:
-    case XENVER_platform_parameters:
-    case XENVER_get_features:
-        /* These sub-ops ignore the permission checks and return data. */
-        return 0;
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
+                            VERSION__XEN_VERSION, NULL);
     case XENVER_extraversion:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_EXTRAVERSION, NULL);
     case XENVER_compile_info:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_COMPILE_INFO, NULL);
     case XENVER_capabilities:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_CAPABILITIES, NULL);
     case XENVER_changeset:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_CHANGESET, NULL);
+    case XENVER_platform_parameters:
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
+                            VERSION__XEN_PLATFORM_PARAMETERS, NULL);
+    case XENVER_get_features:
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
+                            VERSION__XEN_GET_FEATURES, NULL);
     case XENVER_pagesize:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_PAGESIZE, NULL);
     case XENVER_guest_handle:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_GUEST_HANDLE, NULL);
     case XENVER_commandline:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_COMMANDLINE, NULL);
     case XENVER_build_id:
-        return avc_has_perm(dsid, SECINITSID_XEN, SECCLASS_VERSION,
+        return avc_has_perm(dsid, tsid, SECCLASS_VERSION,
                             VERSION__XEN_BUILD_ID, NULL);
     default:
         return -EPERM;
     }
 }
 
+static int flask_xen_version (uint32_t op)
+{
+    return domain_has_xen_version(current->domain, SECINITSID_XEN, op);
+}
+
 static int flask_domain_resource_map(struct domain *d)
 {
     return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__RESOURCE_MAP);
@@ -1738,6 +1748,14 @@ static int flask_argo_send(const struct domain *d, const struct domain *t)
 
 #endif
 
+#ifdef CONFIG_XEN_NESTED
+static int flask_nested_xen_version(const struct domain *d, unsigned int op)
+{
+    return domain_has_xen_version(d, SECINITSID_NESTEDXEN, op);
+}
+
+#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);
 
@@ -1877,6 +1895,9 @@ static struct xsm_operations flask_ops = {
     .argo_register_any_source = flask_argo_register_any_source,
     .argo_send = flask_argo_send,
 #endif
+#ifdef CONFIG_XEN_NESTED
+    .nested_xen_version = flask_nested_xen_version,
+#endif
 };
 
 void __init flask_init(const void *policy_buffer, size_t policy_size)
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 194d743a71..7e0d5aa7bf 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -510,6 +510,8 @@ class security
 #
 class version
 {
+# Basic information
+    xen_version
 # Extra informations (-unstable).
     xen_extraversion
 # Compile information of the hypervisor.
@@ -518,6 +520,10 @@ class version
     xen_capabilities
 # Source code changeset.
     xen_changeset
+# Hypervisor virt start
+    xen_platform_parameters
+# Query for bitmap of platform features
+    xen_get_features
 # Page size the hypervisor uses.
     xen_pagesize
 # An value that the control stack can choose.
diff --git a/xen/xsm/flask/policy/initial_sids b/xen/xsm/flask/policy/initial_sids
index 7eca70d339..c684cda873 100644
--- a/xen/xsm/flask/policy/initial_sids
+++ b/xen/xsm/flask/policy/initial_sids
@@ -15,4 +15,5 @@ sid irq
 sid device
 sid domU
 sid domDM
+sid nestedxen
 # FLASK
-- 
2.17.1


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

  parent reply	other threads:[~2019-06-20  0:31 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-20  0:30 [Xen-devel] [RFC 0/9] The Xen Blanket: hypervisor interface for PV drivers on nested Xen Christopher Clark
2019-06-20  0:30 ` [Xen-devel] [RFC 1/9] x86/guest: code movement to separate Xen detection from guest functions Christopher Clark
2019-06-20  0:30 ` [Xen-devel] [RFC 2/9] x86: Introduce Xen detection as separate logic from Xen Guest support Christopher Clark
2019-06-20  0:30 ` [Xen-devel] [RFC 3/9] x86/nested: add nested_xen_version hypercall Christopher Clark
2019-06-20  0:30 ` Christopher Clark [this message]
2019-06-20  0:30 ` [Xen-devel] [RFC 5/9] x86/nested, xsm: add nested_memory_op hypercall Christopher Clark
2019-06-20  0:30 ` [Xen-devel] [RFC 6/9] x86/nested, xsm: add nested_hvm_op hypercall Christopher Clark
2019-06-20  0:30 ` [Xen-devel] [RFC 7/9] x86/nested, xsm: add nested_grant_table_op hypercall Christopher Clark
2019-06-20  0:30 ` [Xen-devel] [RFC 8/9] x86/nested, xsm: add nested_event_channel_op hypercall Christopher Clark
2019-06-20  0:30 ` [Xen-devel] [RFC 9/9] x86/nested, xsm: add nested_schedop_shutdown hypercall Christopher Clark
2019-06-20  4:18 ` [Xen-devel] [RFC 0/9] The Xen Blanket: hypervisor interface for PV drivers on nested Xen Juergen Gross
2019-06-20  8:39   ` Paul Durrant
2019-06-21  5:51     ` Christopher Clark

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190620003053.21993-5-christopher.w.clark@gmail.com \
    --to=christopher.w.clark@gmail.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=ian.jackson@eu.citrix.com \
    --cc=jbeulich@suse.com \
    --cc=jgross@suse.com \
    --cc=persaur@gmail.com \
    --cc=roger.pau@citrix.com \
    --cc=wl@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.