From patchwork Thu Jun 20 00:30:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christopher Clark X-Patchwork-Id: 11005605 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AAC8114E5 for ; Thu, 20 Jun 2019 00:33:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9661D288C7 for ; Thu, 20 Jun 2019 00:33:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8A76F288CB; Thu, 20 Jun 2019 00:33:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=2.0 tests=BAYES_00,DKIM_ADSP_CUSTOM_MED, DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B0261288C7 for ; Thu, 20 Jun 2019 00:33:13 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hdkz8-0000Bf-R7; Thu, 20 Jun 2019 00:31:26 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1hdkz6-0000Aw-W7 for xen-devel@lists.xenproject.org; Thu, 20 Jun 2019 00:31:25 +0000 X-Inumbo-ID: bb0a0b81-92f2-11e9-8980-bc764e045a96 Received: from mail-io1-xd44.google.com (unknown [2607:f8b0:4864:20::d44]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id bb0a0b81-92f2-11e9-8980-bc764e045a96; Thu, 20 Jun 2019 00:31:23 +0000 (UTC) Received: by mail-io1-xd44.google.com with SMTP id k20so13512ios.10 for ; Wed, 19 Jun 2019 17:31:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Lzz+KQrHRLJ/adNCZGvpyblUPrhS5dxCfOzVt9up/WQ=; b=pTPwI0Z7koqx/eoEznnAfrOJtcnFEsATY7Oam3HIbz9/XtS3nnA2IEiTlJQNH3ptl3 1MlJQgyUclYOu3hIqof2O43eDDTaZ62zP0VVTDXXROW8tE1ES0+WMDIUPcT658ZRyOa9 q6FwlGmO+PXWV4yOLo1gnJFAElQY7oxdchHJ2D14fQMdNQqs5fMcgYm3CrysF76cqsB1 LPbdbPYcUgzIPuj4foVDSPWthWmuErh9WxXWUkrIKzBDz1R3pydVEl01KKwZGVbedXkk Jc748Sxr1WLiKPhfAyATSR1e/wGoKclt7vH/NjIaM0UlC5n7azlvNm+lnqd4nMiLryVO l7Kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Lzz+KQrHRLJ/adNCZGvpyblUPrhS5dxCfOzVt9up/WQ=; b=JqV9sUzU6FDWEgQwsrwVWWx/xzTyUl2MD3HCpDgwploNxsuPsUDXKFIEOpHltWmE7k ZcymE9hddZPnY/TvkVPEGhvX9z4djz4vnnrt8/SxsaeV+mLimlWJywA+6FIbSBZ6zmlK bdigHCxW0RqSIl1mEs5b8lRJ+aAHMsENmKHsoI2sVOb096SF2rvY/xA115sBW8bCdak7 eUU2ig7hlf5Y53/OXDzVcIbN5FQ0SztgFhbzCxoSeDFLr9lvSAaJqjyg35nrfpfC+R/1 oTMdqeMKPSkQaVMmfhoeE9S4UYmEiPReMA1InKkkMDeMwIhHVIqdB76dazK+hcIfOdiB 8xXw== X-Gm-Message-State: APjAAAVcCj+ZKHPXEt2HSPLCSk52Eosipq9pdd6w5cHC3KuZwhP6qi7H a2wobPTWWGvqrHTuGc24m5SMcqgmGO0= X-Google-Smtp-Source: APXvYqwk2d7Lwq7qU6NyK3Q2aSmUrmCQ11RuTGQFzxhU0klz2hcDAAtFpKCev7NfZkbr82du/Pknvg== X-Received: by 2002:a02:6a19:: with SMTP id l25mr95790256jac.123.1560990682225; Wed, 19 Jun 2019 17:31:22 -0700 (PDT) Received: from desktop.ice.pyrology.org (static-50-53-74-115.bvtn.or.frontiernet.net. [50.53.74.115]) by smtp.gmail.com with ESMTPSA id e188sm22579016ioa.3.2019.06.19.17.31.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Jun 2019 17:31:21 -0700 (PDT) From: Christopher Clark To: xen-devel@lists.xenproject.org Date: Wed, 19 Jun 2019 17:30:48 -0700 Message-Id: <20190620003053.21993-5-christopher.w.clark@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190620003053.21993-1-christopher.w.clark@gmail.com> References: <20190620003053.21993-1-christopher.w.clark@gmail.com> Subject: [Xen-devel] [RFC 4/9] XSM: Add hook for nested xen version op; revises non-nested version op X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Wei Liu , Andrew Cooper , Ian Jackson , Rich Persaud , Jan Beulich , Daniel De Graaf , =?utf-8?q?Roger_Pau_Monn=C3=A9?= MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 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