From patchwork Tue Jul 5 17:44:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel De Graaf X-Patchwork-Id: 9215011 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D3EEB60752 for ; Tue, 5 Jul 2016 17:48:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C5D9227F90 for ; Tue, 5 Jul 2016 17:48:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B8CF827F96; Tue, 5 Jul 2016 17:48:01 +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=-4.2 required=2.0 tests=BAYES_00, 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 AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 8223127F90 for ; Tue, 5 Jul 2016 17:48:00 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bKUP1-000515-Ch; Tue, 05 Jul 2016 17:44:55 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bKUP0-00050z-Gr for xen-devel@lists.xenproject.org; Tue, 05 Jul 2016 17:44:54 +0000 Received: from [85.158.139.211] by server-9.bemta-5.messagelabs.com id 1E/75-10998-512FB775; Tue, 05 Jul 2016 17:44:53 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrELMWRWlGSWpSXmKPExsXCoZPKqSvyqTr c4OZ5K4vvWyYzOTB6HP5whSWAMYo1My8pvyKBNWP/ui6WgpNhFe1L1rI1MC5172Lk5JAQ8JOY cvQiexcjFwenwBkWiVW9vSwgjoTAOUaJC93nmEEcIYF2Ronn546yQzhbGSUurulhA+lnE9CVW HBwJROILSKgJHFv1WQmkCJmgYeMEk82HWYBSQgLWEsc/QXSzcnBIqAqsfx0IyOIzSvgKvFu4X R2iEPkJG6e62SewMizgJFhFaNGcWpRWWqRrqGZXlJRZnpGSW5iZo6uoYGpXm5qcXFiempOYlK xXnJ+7iZGoP8ZgGAH4/nTnocYJTmYlER5815XhwvxJeWnVGYkFmfEF5XmpBYfYpTh4FCS4N34 ASgnWJSanlqRlpkDDESYtAQHj5II7x2QNG9xQWJucWY6ROoUoy7HlgU31jIJseTl56VKifNeA CkSACnKKM2DGwGLikuMslLCvIxARwnxFKQW5WaWoMq/YhTnYFQS5t0FMoUnM68EbtMroCOYgI 746QJ2REkiQkqqgTF29vnCE+GX+Z9VGk5vTQsSu3HwueHvnBe2V09r7MpY+t6ntLHoXU5V1ec S+VmLhas7yu+VeTkwZCrGfQoJFL+YVqN9//u76VP23jgvJ+M8yzw48JPGjpYYs4nWk9q/K4pW Jx2zSZS2unu+13zxy3/N2Va/G7asNDXlE5laeWR538WHMzan2SixFGckGmoxFxUnAgBDXxpGh QIAAA== X-Env-Sender: dgdegra@tycho.nsa.gov X-Msg-Ref: server-4.tower-206.messagelabs.com!1467740691!48655323!1 X-Originating-IP: [8.44.101.9] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 8.46; banners=-,-,- X-VirusChecked: Checked Received: (qmail 43248 invoked from network); 5 Jul 2016 17:44:52 -0000 Received: from smtp.nsa.gov (HELO emsm-gh1-uea11.nsa.gov) (8.44.101.9) by server-4.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 5 Jul 2016 17:44:52 -0000 X-IronPort-AV: E=Sophos;i="5.26,580,1459814400"; d="scan'208";a="17403929" IronPort-PHdr: =?us-ascii?q?9a23=3ABJupNB+/rloUAv9uRHKM819IXTAuvvDOBiVQ1KB9?= =?us-ascii?q?2+8cTK2v8tzYMVDF4r011RmSDN2dsa4P0rOK+4nbGkU4qa6bt34DdJEeHzQksu?= =?us-ascii?q?4x2zIaPcieFEfgJ+TrZSFpVO5LVVti4m3peRMNQJW2WVTerzWI4CIIHV2nbEwu?= =?us-ascii?q?d7yzQNKZ1p3rn8mJuLTrKz1SgzS8Zb4gZD6Xli728vcsvI15N6wqwQHIqHYbM8?= =?us-ascii?q?5fxGdvOE7B102kvpT41NdZ/i9Ro/Ms8dJbGeW/JvxgDO9lFjBuD0QZrI2u70GC?= =?us-ascii?q?HkOz4S4MX2NTnhdWDgzt6BDhQoy3oib8rvB62iSRIYvxV79ndy6l6vJHQRnphS?= =?us-ascii?q?NPGzNx33veg8I42K5UrB+uvRVX35/fYIbTMuF3OKzaY4VJFiJ6Qs9NWnkZUcuH?= =?us-ascii?q?ZIwVAr9EZLwAog=3D=3D?= X-IPAS-Result: =?us-ascii?q?A2EkBwCQ8HtX/wHyM5BcHAEBgyBWfKdmAYl0hVyEBhIMgXC?= =?us-ascii?q?ECoE2TAEBAQEBAQICYieCMoEDW4EuDiiBKYgwuzIxjx6CXwuDBwWIGpB5hgmIP?= =?us-ascii?q?gKBaE6HKgyFPJAKVIIIHIFoIDKIVAEBAQ?= Received: from unknown (HELO tarius.tycho.ncsc.mil) ([144.51.242.1]) by emsm-gh1-uea11.nsa.gov with ESMTP; 05 Jul 2016 17:44:48 +0000 Received: from moss-nexus.infosec.tycho.ncsc.mil (moss-nexus [192.168.25.48]) by tarius.tycho.ncsc.mil (8.14.4/8.14.4) with ESMTP id u65Hij9v011803; Tue, 5 Jul 2016 13:44:46 -0400 From: Daniel De Graaf To: xen-devel@lists.xenproject.org Date: Tue, 5 Jul 2016 13:44:43 -0400 Message-Id: <1467740683-16547-1-git-send-email-dgdegra@tycho.nsa.gov> X-Mailer: git-send-email 2.7.4 Cc: Doug Goldstein , Daniel De Graaf , Ian Jackson , Jan Beulich Subject: [Xen-devel] [PATCH v4] xsm: add a default policy to .init.data X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP This adds a Kconfig option and support for including the XSM policy from tools/flask/policy in the hypervisor so that the bootloader does not need to provide a policy to get sane behavior from an XSM-enabled hypervisor. The policy provided by the bootloader, if present, will override the built-in policy. The XSM policy is not moved out of tools because that remains the primary location for installing and configuring the policy. Signed-off-by: Daniel De Graaf Reviewed-by: Konrad Rzeszutek Wilk --- Changes from v3: - Make default Kconfig value depend on the presence of checkpolicy - Use proper __initconst label on generated data - Place generated symbols in xsm.h to enforce type matching Config.mk | 6 ++++++ INSTALL | 10 ++++++++-- docs/misc/xen-command-line.markdown | 16 +++++++++------- docs/misc/xsm-flask.txt | 30 +++++++++++++++--------------- xen/common/Kconfig | 20 ++++++++++++++++++++ xen/include/xsm/xsm.h | 7 +++++++ xen/xsm/flask/.gitignore | 1 + xen/xsm/flask/Makefile | 11 +++++++++++ xen/xsm/flask/gen-policy.py | 23 +++++++++++++++++++++++ xen/xsm/xsm_core.c | 15 ++++++++++++++- 10 files changed, 114 insertions(+), 25 deletions(-) create mode 100644 xen/xsm/flask/.gitignore create mode 100644 xen/xsm/flask/gen-policy.py diff --git a/Config.mk b/Config.mk index 723e129..01316ae 100644 --- a/Config.mk +++ b/Config.mk @@ -147,6 +147,12 @@ export XEN_HAS_BUILD_ID=y build_id_linker := --build-id=sha1 endif +ifndef XEN_HAS_CHECKPOLICY + CHECKPOLICY ?= checkpolicy + XEN_HAS_CHECKPOLICY := $(shell $(CHECKPOLICY) -h 2>&1 | grep -q xen && echo y || echo n) + export XEN_HAS_CHECKPOLICY +endif + # as-insn: Check whether assembler supports an instruction. # Usage: cflags-y += $(call as-insn "insn",option-yes,option-no) as-insn = $(if $(shell echo 'void _(void) { asm volatile ( $(2) ); }' \ diff --git a/INSTALL b/INSTALL index 616a67a..9759354 100644 --- a/INSTALL +++ b/INSTALL @@ -269,10 +269,16 @@ Building the python tools may fail unless certain options are passed to setup.py. Config.mk contains additional info how to use this variable. PYTHON_PREFIX_ARG= -The hypervisor may be build with XSM/Flask support, which can be changed +The hypervisor may be built with XSM/Flask support, which can be changed by running: make -C xen menuconfig -and enabling XSM/Flask in the 'Common Features' menu. +and enabling XSM/Flask in the 'Common Features' menu. A security policy +is required to use XSM/Flask; if the SELinux policy compiler is +available, the policy from tools can be included in the hypervisor. +This option is enabled by default if XSM is enabled and the compiler +(checkpolicy) is found. The location of this executable can be set +using the environment variable. +CHECKPOLICY= Do a build for coverage. coverage=y diff --git a/docs/misc/xen-command-line.markdown b/docs/misc/xen-command-line.markdown index 2a088ca..5500242 100644 --- a/docs/misc/xen-command-line.markdown +++ b/docs/misc/xen-command-line.markdown @@ -712,13 +712,15 @@ enabled by running either: with untrusted guests. If a policy is provided by the bootloader, it will be loaded; errors will be reported to the ring buffer but will not prevent booting. The policy can be changed to enforcing mode using "xl setenforce". -* `enforcing`: This requires a security policy to be provided by the bootloader - and will enter enforcing mode prior to the creation of domain 0. If a valid - policy is not provided, the hypervisor will not continue booting. -* `late`: This disables loading of the security policy from the bootloader. - FLASK will be enabled but will not enforce access controls until a policy is - loaded by a domain using "xl loadpolicy". Once a policy is loaded, FLASK will - run in enforcing mode unless "xl setenforce" has changed that setting. +* `enforcing`: This will cause the security server to enter enforcing mode prior + to the creation of domain 0. If an valid policy is not provided by the + bootloader and no built-in policy is present, the hypervisor will not continue + booting. +* `late`: This disables loading of the built-in security policy or the policy + provided by the bootloader. FLASK will be enabled but will not enforce access + controls until a policy is loaded by a domain using "xl loadpolicy". Once a + policy is loaded, FLASK will run in enforcing mode unless "xl setenforce" has + changed that setting. * `disabled`: This causes the XSM framework to revert to the dummy module. The dummy module provides the same security policy as is used when compiling the hypervisor without support for XSM. The xsm\_op hypercall can also be used to diff --git a/docs/misc/xsm-flask.txt b/docs/misc/xsm-flask.txt index 2f42585..62f15dd 100644 --- a/docs/misc/xsm-flask.txt +++ b/docs/misc/xsm-flask.txt @@ -141,21 +141,21 @@ only type enforcement is used and the user and role are set to system_u and system_r for all domains. The FLASK security framework is mostly configured using a security policy file. -This policy file is not normally generated during the Xen build process because -it relies on the SELinux compiler "checkpolicy"; run - - make -C tools/flask/policy - -to compile the example policy included with Xen. The policy is generated from -definition files under this directory. Most changes to security policy will -involve creating or modifying modules found in tools/flask/policy/modules/. The -modules.conf file there defines what modules are enabled and has short -descriptions of each module. - -The XSM policy file needs to be copied to /boot and loaded as a module by grub. -The exact position of the module does not matter as long as it is after the Xen -kernel; it is normally placed either just above the dom0 kernel or at the end. -Once dom0 is running, the policy can be reloaded using "xl loadpolicy". +It relies on the SELinux compiler "checkpolicy"; if this is available, the +policy will be compiled as part of the tools build. If hypervisor support for a +built-in policy is enabled ("Compile Xen with a built-in security policy"), the +policy will be built during the hypervisor build. + +The policy is generated from definition files in tools/flask/policy. Most +changes to security policy will involve creating or modifying modules found in +tools/flask/policy/modules/. The modules.conf file there defines what modules +are enabled and has short descriptions of each module. + +If not using the built-in policy, the XSM policy file needs to be copied to +/boot and loaded as a module by grub. The exact position and filename of the +module does not matter as long as it is after the Xen kernel; it is normally +placed either just above the dom0 kernel or at the end. Once dom0 is running, +the policy can be reloaded using "xl loadpolicy". The example policy included with Xen demonstrates most of the features of FLASK that can be used without dom0 disaggregation. The main types for domUs are: diff --git a/xen/common/Kconfig b/xen/common/Kconfig index daab832..51afa24 100644 --- a/xen/common/Kconfig +++ b/xen/common/Kconfig @@ -46,6 +46,10 @@ config HAS_BUILD_ID string option env="XEN_HAS_BUILD_ID" +config HAS_CHECKPOLICY + string + option env="XEN_HAS_CHECKPOLICY" + # Enable/Disable kexec support config KEXEC bool "kexec support" @@ -143,6 +147,22 @@ config FLASK_AVC_STATS If unsure, say Y. +config XSM_POLICY + bool "Compile Xen with a built-in security policy" + default y if HAS_CHECKPOLICY = "y" + depends on XSM + ---help--- + This includes a default XSM policy in the hypervisor so that the + bootloader does not need to load a policy to get sane behavior from an + XSM-enabled hypervisor. If this is disabled, a policy must be + provided by the bootloader or by Domain 0. Even if this is enabled, a + policy provided by the bootloader will override it. + + This requires that the SELinux policy compiler (checkpolicy) be + available when compiling the hypervisor. + + If unsure, say Y. + # Enable schedulers menu "Schedulers" visible if EXPERT = "y" diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h index 4b8843d..912c401 100644 --- a/xen/include/xsm/xsm.h +++ b/xen/include/xsm/xsm.h @@ -762,6 +762,13 @@ static inline void flask_init(void) } #endif +#ifdef CONFIG_XSM_POLICY +extern const unsigned char xsm_init_policy[]; +extern const int xsm_init_policy_size; +#else +#define xsm_init_policy NULL +#endif + #else /* CONFIG_XSM */ #include diff --git a/xen/xsm/flask/.gitignore b/xen/xsm/flask/.gitignore new file mode 100644 index 0000000..024edbe --- /dev/null +++ b/xen/xsm/flask/.gitignore @@ -0,0 +1 @@ +/policy.c diff --git a/xen/xsm/flask/Makefile b/xen/xsm/flask/Makefile index 12fc3a9..6335a72 100644 --- a/xen/xsm/flask/Makefile +++ b/xen/xsm/flask/Makefile @@ -27,6 +27,17 @@ $(FLASK_H_FILES): $(FLASK_H_DEPEND) $(AV_H_FILES): $(AV_H_DEPEND) $(CONFIG_SHELL) policy/mkaccess_vector.sh $(AWK) $(AV_H_DEPEND) +obj-$(CONFIG_XSM_POLICY) += policy.o + +POLICY_SRC := $(XEN_ROOT)/tools/flask/policy/xenpolicy-$(XEN_FULLVERSION) + +policy.bin: FORCE + $(MAKE) -C $(XEN_ROOT)/tools/flask/policy + cmp -s $(POLICY_SRC) $@ || cp $(POLICY_SRC) $@ + +policy.c: policy.bin gen-policy.py + $(PYTHON) gen-policy.py < $< > $@ + .PHONY: clean clean:: rm -f $(ALL_H_FILES) *.o $(DEPS) diff --git a/xen/xsm/flask/gen-policy.py b/xen/xsm/flask/gen-policy.py new file mode 100644 index 0000000..13e86b0 --- /dev/null +++ b/xen/xsm/flask/gen-policy.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +import sys + +policy_size = 0 + +sys.stdout.write(""" +/* This file is autogenerated by gen_policy.py */ +#include +#include + +const unsigned char xsm_init_policy[] __initconst = { +""") + +for char in sys.stdin.read(): + sys.stdout.write(" 0x%02x," % ord(char)) + policy_size = policy_size + 1 + if policy_size % 13 == 0: + sys.stdout.write("\n") + +sys.stdout.write(""" +}; +const int __initconst xsm_init_policy_size = %d; +""" % policy_size) diff --git a/xen/xsm/xsm_core.c b/xen/xsm/xsm_core.c index 8df1a3c..bab68d5 100644 --- a/xen/xsm/xsm_core.c +++ b/xen/xsm/xsm_core.c @@ -36,6 +36,17 @@ static inline int verify(struct xsm_operations *ops) return 0; } +static inline void xsm_policy_init(void) +{ +#ifdef CONFIG_XSM_POLICY + if ( policy_size == 0 ) + { + policy_buffer = (char*)xsm_init_policy; + policy_size = xsm_init_policy_size; + } +#endif +} + static int __init xsm_core_init(void) { if ( verify(&dummy_xsm_ops) ) @@ -46,6 +57,7 @@ static int __init xsm_core_init(void) } xsm_ops = &dummy_xsm_ops; + xsm_policy_init(); flask_init(); return 0; @@ -98,7 +110,8 @@ int __init xsm_dt_init(void) ret = xsm_core_init(); - xfree(policy_buffer); + if ( policy_buffer != xsm_init_policy ) + xfree(policy_buffer); return ret; }