These patches update the example FLASK policy shipped with Xen and enable its build if the required tools are present. The third patch requires rerunning autoconf to update tools/configure. [PATCH 1/3] flask/policy: sort dom0 accesses [PATCH 2/3] flask/policy: rework policy build system [PATCH 3/3] tools/flask: add FLASK policy to build
For the example policy shipped with Xen, it makes sense to allow dom0 access to all system calls so that policy does not need to be updated for each new hypervisor or toolstack feature used. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/flask/policy/policy/modules/xen/xen.te | 60 ++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/tools/flask/policy/policy/modules/xen/xen.te b/tools/flask/policy/policy/modules/xen/xen.te index 955fd8b..454e27e 100644 --- a/tools/flask/policy/policy/modules/xen/xen.te +++ b/tools/flask/policy/policy/modules/xen/xen.te @@ -51,20 +51,58 @@ type device_t, resource_type; ################################################################################ # -# Rules required to boot the hypervisor and dom0 +# Allow dom0 access to all sysctls, devices, and the security server. +# +# While this could be written more briefly using wildcards, the permissions are +# listed out to make removing specific permissions simpler. # ################################################################################ -allow dom0_t xen_t:xen { kexec readapic writeapic mtrr_read mtrr_add mtrr_del - physinfo heap quirk readconsole writeconsole settime getcpuinfo - microcode cpupool_op pm_op tmem_control getscheduler setscheduler }; -allow dom0_t xen_t:mmu { memorymap }; -allow dom0_t security_t:security { check_context compute_av compute_create - compute_member load_policy compute_relabel compute_user setenforce - setbool setsecparam add_ocontext del_ocontext }; - -allow dom0_t dom0_t:domain { getdomaininfo getvcpuinfo getvcpuaffinity }; +allow dom0_t xen_t:xen { + settime tbufcontrol readconsole clearconsole perfcontrol mtrr_add + mtrr_del mtrr_read microcode physinfo quirk writeconsole readapic + writeapic privprofile nonprivprofile kexec firmware sleep frequency + getidle debug getcpuinfo heap pm_op mca_op lockprof cpupool_op tmem_op + tmem_control getscheduler setscheduler +}; +allow dom0_t xen_t:mmu memorymap; + +# Allow dom0 to use these domctls on itself. For domctls acting on other +# domains, see the definitions of create_domain and manage_domain. +allow dom0_t dom0_t:domain { + setvcpucontext max_vcpus setvcpuaffinity getvcpuaffinity getscheduler + getdomaininfo getvcpuinfo getvcpucontext setdomainmaxmem setdomainhandle + setdebugging hypercall settime setaddrsize getaddrsize trigger + getextvcpucontext setextvcpucontext getvcpuextstate setvcpuextstate + getpodtarget setpodtarget set_misc_info set_virq_handler +}; +allow dom0_t dom0_t:domain2 { + set_cpuid gettsc settsc setscheduler +}; allow dom0_t dom0_t:resource { add remove }; +# 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 +# Xen''s security policy. +allow dom0_t security_t:security { + compute_av compute_create compute_member compute_relabel compute_user +}; + +# Allow string/SID conversions (for "xl list -Z" and similar) +allow dom0_t security_t:security check_context; + +# Allow flask-label-pci to add and change labels +allow dom0_t security_t:security { add_ocontext del_ocontext }; + +# Allow performance parameters of the security server to be tweaked +allow dom0_t security_t:security setsecparam; + +# Allow changing the security policy +allow dom0_t security_t:security { load_policy setenforce setbool }; + +# Audit policy change events even when they are allowed +auditallow dom0_t security_t:security { load_policy setenforce setbool }; + admin_device(dom0_t, device_t) admin_device(dom0_t, irq_t) admin_device(dom0_t, ioport_t) @@ -72,8 +110,6 @@ admin_device(dom0_t, iomem_t) domain_comms(dom0_t, dom0_t) -auditallow dom0_t security_t:security { load_policy setenforce setbool }; - # Allow all domains to use (unprivileged parts of) the tmem hypercall allow domain_type xen_t:xen tmem_op; -- 1.8.1.2
Daniel De Graaf
2013-Feb-13 16:01 UTC
[PATCH 2/3] flask/policy: rework policy build system
This adds the ability to define security classes and access vectors in FLASK policy not defined by the hypervisor, for the use of stub domains or applications without their own security policies. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- tools/flask/policy/Makefile | 203 +++++++++-------------------- tools/flask/policy/policy/access_vectors | 24 ++++ tools/flask/policy/policy/global_booleans | 5 - tools/flask/policy/policy/global_tunables | 5 +- tools/flask/policy/policy/initial_sids | 4 +- tools/flask/policy/policy/security_classes | 8 ++ 6 files changed, 96 insertions(+), 153 deletions(-) create mode 100644 tools/flask/policy/policy/access_vectors delete mode 100644 tools/flask/policy/policy/global_booleans create mode 100644 tools/flask/policy/policy/security_classes diff --git a/tools/flask/policy/Makefile b/tools/flask/policy/Makefile index 3f5aa38..e666f3e 100644 --- a/tools/flask/policy/Makefile +++ b/tools/flask/policy/Makefile @@ -1,117 +1,86 @@ -# -# Makefile for the security policy. -# -# Targets: -# -# install - compile and install the policy configuration. -# load - compile, install, and load the policy configuration. -# reload - compile, install, and load/reload the policy configuration. -# policy - compile the policy configuration locally for testing/development. -# -# The default target is ''policy''. -# +XEN_ROOT=$(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk ######################################## # # Configurable portions of the Makefile # +######################################## -# Policy version -# By default, checkpolicy will create the highest -# version policy it supports. Setting this will -# override the version. -OUTPUT_POLICY = 24 - -# Policy Type -# xen -# xen-mls -TYPE = xen - -# Policy Name -# If set, this will be used as the policy -# name. Otherwise xenpolicy will be -# used for the name. -# NAME = xenpolicy - -# Number of MLS Sensitivities -# The sensitivities will be s0 to s(MLS_SENS-1). -# Dominance will be in increasing numerical order -# with s0 being lowest. -# MLS_SENS = 16 +CONFIG_MLS ?= n -# Number of MLS Categories +# Number of available MLS sensitivities and categories. +# The sensitivities will be s0 to s(MLS_SENS-1). Dominance will be in +# increasing numerical order with s0 being lowest. +MLS_SENS ?= 16 # The categories will be c0 to c(MLS_CATS-1). -# MLS_CATS = 256 +MLS_CATS ?= 256 -# Uncomment this to disable command echoing -# QUIET:=@ +# executable paths +CHECKPOLICY ?= checkpolicy +M4 ?= m4 ######################################## # -# NO OPTIONS BELOW HERE +# End of configuration options # +######################################## -# executable paths -PREFIX := /usr -BINDIR := $(PREFIX)/bin -SBINDIR := $(PREFIX)/sbin -CHECKPOLICY := $(BINDIR)/checkpolicy -LOADPOLICY := $(SBINDIR)/flask-loadpolicy +# Policy version +# By default, checkpolicy creates the highest version policy it supports. Force +# the use of version 24 which is the highest that Xen supports, and the first to +# include the Xen policy type (needed for static device policy). +OUTPUT_POLICY = 24 + +POLICY_FILENAME = xenpolicy.$(OUTPUT_POLICY) +POLICY_LOADPATH = $(DESTDIR)/boot # policy source layout POLDIR := policy MODDIR := $(POLDIR)/modules + +# Classes and access vectors defined in the hypervisor. Changes to these require +# a recompile of both the hypervisor and security policy. FLASKDIR := ../../../xen/xsm/flask/policy SECCLASS := $(FLASKDIR)/security_classes -ISIDS := $(FLASKDIR)/initial_sids +ISID_DECLS := $(FLASKDIR)/initial_sids AVS := $(FLASKDIR)/access_vectors +# Additional classes and access vectors defined by local policy +SECCLASS += $(POLDIR)/security_classes +AVS += $(POLDIR)/access_vectors + +# Other policy components +M4SUPPORT := $(wildcard $(POLDIR)/support/*.spt) +MLSSUPPORT := $(POLDIR)/mls +USERS := $(POLDIR)/users +CONSTRAINTS := $(POLDIR)/constraints +ISID_DEFS := $(POLDIR)/initial_sids + # config file paths GLOBALTUN := $(POLDIR)/global_tunables -GLOBALBOOL := $(POLDIR)/global_booleans MOD_CONF := $(POLDIR)/modules.conf -TUNABLES := $(POLDIR)/tunables.conf -BOOLEANS := $(POLDIR)/booleans.conf - -# install paths - -DESTDIR = /boot -INSTALLDIR = $(DESTDIR) -LOADPATH = $(INSTALLDIR)/$(POLVER) -# default MLS sensitivity and category settings. -MLS_SENS ?= 16 -MLS_CATS ?= 256 +# checkpolicy can use the #line directives provided by -s for error reporting: +M4PARAM := -D self_contained_policy -s +CHECKPOLICY_PARAM := -t Xen -c $(OUTPUT_POLICY) # enable MLS if requested. -ifneq ($(findstring -mls,$(TYPE)),) +ifneq ($(CONFIG_MLS),n) M4PARAM += -D enable_mls - CHECKPOLICY += -M -endif - -ifeq ($(NAME),) - NAME := xenpolicy -endif - -PV := $(shell $(CHECKPOLICY) -V |cut -f 1 -d '' '') - -ifneq ($(OUTPUT_POLICY),) - CHECKPOLICY += -c $(OUTPUT_POLICY) - POLVER = $(NAME).$(OUTPUT_POLICY) -else - POLVER +=$(NAME).$(PV) + CHECKPOLICY_PARAM += -M endif # Always define these because they are referenced even in non-MLS policy M4PARAM += -D mls_num_sens=$(MLS_SENS) -D mls_num_cats=$(MLS_CATS) -M4SUPPORT = $(wildcard $(POLDIR)/support/*.spt) +# Find modules ALL_LAYERS := $(filter-out $(MODDIR)/CVS,$(shell find $(wildcard $(MODDIR)/*) -maxdepth 0 -type d)) # sort here since it removes duplicates, which can happen # when a generated file is already generated -DETECTED_MODS := $(sort $(foreach dir,$(ALL_LAYERS),$(wildcard $(dir)/*.te))) +DETECTED_MODS := $(sort $(foreach dir,$(ALL_LAYERS),$(wildcard $(dir)/*.te))) # modules.conf setting for policy configuration MODENABLED := on @@ -122,81 +91,27 @@ ENABLED_MODS := $(foreach mod,$(shell awk ''/^[[:blank:]]*[[:alpha:]]/{ if ($$3 ALL_MODULES := $(filter $(ENABLED_MODS),$(DETECTED_MODS)) ALL_INTERFACES := $(ALL_MODULES:.te=.if) -ALL_TE_FILES := $(ALL_MODULES) - -PRE_TE_FILES := $(SECCLASS) $(ISIDS) $(AVS) $(M4SUPPORT) $(POLDIR)/mls -POST_TE_FILES := $(POLDIR)/users $(POLDIR)/constraints $(POLDIR)/initial_sids -POLICY_SECTIONS := $(PRE_TE_FILES) $(ALL_INTERFACES) $(GLOBALBOOL) $(GLOBALTUN) $(ALL_TE_FILES) $(POST_TE_FILES) - -######################################## -# -# default action: build policy locally -# -default: policy +# The order of these files is important +POLICY_SECTIONS := $(SECCLASS) $(ISID_DECLS) $(AVS) +POLICY_SECTIONS += $(M4SUPPORT) $(MLSSUPPORT) +POLICY_SECTIONS += $(ALL_INTERFACES) +POLICY_SECTIONS += $(GLOBALTUN) +POLICY_SECTIONS += $(ALL_MODULES) +POLICY_SECTIONS += $(USERS) $(CONSTRAINTS) $(ISID_DEFS) -policy: $(POLVER) +all: $(POLICY_FILENAME) -install: $(LOADPATH) +install: $(POLICY_FILENAME) + $(INSTALL_DATA) $^ $(POLICY_LOADPATH) -load: .load_stamp +$(POLICY_FILENAME): policy.conf + $(CHECKPOLICY) $(CHECKPOLICY_PARAM) $^ -o $@ -######################################## -# -# Build a binary policy locally -# -$(POLVER): policy.conf - @echo "Compiling $(NAME) $(POLVER)" - $(QUIET) $(CHECKPOLICY) $^ -o $@ -# Uncomment line below to enable policies for devices -# $(QUIET) $(CHECKPOLICY) -t Xen $^ -o $@ - -######################################## -# -# Install a binary policy -# -$(LOADPATH): policy.conf - @echo "Compiling and installing $(NAME) $(LOADPATH)" - $(QUIET) $(CHECKPOLICY) $^ -o $@ -# Uncomment line below to enable policies for devices -# $(QUIET) $(CHECKPOLICY) -t Xen $^ -o $@ - -######################################## -# -# Load the binary policy -# -.load_stamp: reload -reload: $(LOADPATH) - @echo "Loading $(NAME) $(LOADPATH)" - $(QUIET) $(LOADPOLICY) $(LOADPATH) - @touch .load_stamp - -######################################## -# -# Construct a monolithic policy.conf -# policy.conf: $(POLICY_SECTIONS) - @echo "Creating $(NAME) policy.conf" -# checkpolicy can use the #line directives provided by -s for error reporting: - $(QUIET) m4 -D self_contained_policy $(M4PARAM) -s $^ > $@ + $(M4) $(M4PARAM) $^ > $@ -######################################## -# -# Remove the dontaudit rules from the policy.conf -# -enableaudit: policy.conf - @test -d tmp || mkdir -p tmp - @echo "Removing dontaudit rules from policy.conf" - $(QUIET) grep -v dontaudit policy.conf > tmp/policy.audit - $(QUIET) mv tmp/policy.audit policy.conf - -######################################## -# -# Clean the built policies. -# clean: - rm -fR tmp - rm -f policy.conf - rm -f $(POLVER) + $(RM) tmp policy.conf $(POLICY_FILENAME) -.PHONY: default policy install load reload enableaudit clean +.PHONY: all install clean diff --git a/tools/flask/policy/policy/access_vectors b/tools/flask/policy/policy/access_vectors new file mode 100644 index 0000000..4fd61f1 --- /dev/null +++ b/tools/flask/policy/policy/access_vectors @@ -0,0 +1,24 @@ +# Locally defined access vectors +# +# Define access vectors for the security classes defined in security_classes +# + +# Note: this is an example; the xenstore daemon provided with Xen does +# not yet include XSM support, and the exact permissions may be defined +# differently if such support is added. +class xenstore { + # read from keys owned by the target domain (if permissions allow) + read + # write to keys owned by the target domain (if permissions allow) + write + # change permissions of a key owned by the target domain + chmod + # change the owner of a key which was owned by the target domain + chown_from + # change the owner of a key to the target domain + chown_to + # access a key owned by the target domain without permission + override + # introduce a domain + introduce +} diff --git a/tools/flask/policy/policy/global_booleans b/tools/flask/policy/policy/global_booleans deleted file mode 100644 index 4c13cfb..0000000 --- a/tools/flask/policy/policy/global_booleans +++ /dev/null @@ -1,5 +0,0 @@ -# -# This file is for the declaration of global booleans. -# To change the default value at build time, the booleans.conf -# file should be used. -# diff --git a/tools/flask/policy/policy/global_tunables b/tools/flask/policy/policy/global_tunables index 801b27e..c5da7ae 100644 --- a/tools/flask/policy/policy/global_tunables +++ b/tools/flask/policy/policy/global_tunables @@ -1,6 +1,5 @@ # -# This file is for the declaration of global tunables. -# To change the default value at build time, the booleans.conf -# file should be used. +# This file is for the declaration of global policy tunables, booleans, +# and other components not defined within a specific policy module. # diff --git a/tools/flask/policy/policy/initial_sids b/tools/flask/policy/policy/initial_sids index b70a54e..5de0bbf 100644 --- a/tools/flask/policy/policy/initial_sids +++ b/tools/flask/policy/policy/initial_sids @@ -1,4 +1,6 @@ -# Labels for initial SIDs +# Labels for initial SIDs. These initial SIDs are used by the hypervisor for +# objects created before the policy is loaded or for objects that do not have a +# label defined in some other manner. sid xen gen_context(system_u:system_r:xen_t,s0) sid dom0 gen_context(system_u:system_r:dom0_t,s0) diff --git a/tools/flask/policy/policy/security_classes b/tools/flask/policy/policy/security_classes new file mode 100644 index 0000000..56595e8 --- /dev/null +++ b/tools/flask/policy/policy/security_classes @@ -0,0 +1,8 @@ +# Locally defined security classes +# +# These classes are not used by the hypervisor, but may be used by domains or +# daemons that need to make access control decisions using the hypervisor''s +# security policy. +# +# Access vectors for these classes must be defined in the access_vectors file. +class xenstore -- 1.8.1.2
This patch enables the compilation of the FLASK policy as part of the tools build if the needed prerequisites are present. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov> --- Note: ./autogen.sh nees to be rerun after applying this patch config/Tools.mk.in | 1 + m4/checkpolicy.m4 | 12 ++++++++++++ tools/configure.ac | 10 ++++++++++ tools/flask/Makefile | 4 ++-- 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 m4/checkpolicy.m4 diff --git a/config/Tools.mk.in b/config/Tools.mk.in index 3967e7d..c69c7d2 100644 --- a/config/Tools.mk.in +++ b/config/Tools.mk.in @@ -46,6 +46,7 @@ GIT_HTTP := @githttp@ XENSTAT_XENTOP := @monitors@ LIBXENAPI_BINDINGS := @xenapi@ OCAML_TOOLS := @ocamltools@ +FLASK_POLICY := @xsmpolicy@ CONFIG_MINITERM := @miniterm@ CONFIG_LOMOUNT := @lomount@ CONFIG_OVMF := @ovmf@ diff --git a/m4/checkpolicy.m4 b/m4/checkpolicy.m4 new file mode 100644 index 0000000..f727a7d --- /dev/null +++ b/m4/checkpolicy.m4 @@ -0,0 +1,12 @@ +AC_DEFUN([AC_PROG_CHECKPOLICY], +[dnl + # check for a checkpolicy binary with support for -t xen + AC_CHECK_TOOL([CHECKPOLICY],[checkpolicy],[no]) + + if test "$CHECKPOLICY" != "no"; then + CHECKPOLICYHELP=`$CHECKPOLICY -h | grep xen` + if test "$CHECKPOLICYHELP" = ""; then + CHECKPOLICY=no + fi + fi +]) diff --git a/tools/configure.ac b/tools/configure.ac index de5d085..0d38408 100644 --- a/tools/configure.ac +++ b/tools/configure.ac @@ -28,6 +28,7 @@ m4_include([../m4/path_or_fail.m4]) m4_include([../m4/python_version.m4]) m4_include([../m4/python_devel.m4]) m4_include([../m4/ocaml.m4]) +m4_include([../m4/checkpolicy.m4]) m4_include([../m4/set_cflags_ldflags.m4]) m4_include([../m4/uuid.m4]) m4_include([../m4/pkg.m4]) @@ -42,6 +43,7 @@ AX_ARG_DEFAULT_DISABLE([githttp], [Download GIT repositories via HTTP]) AX_ARG_DEFAULT_ENABLE([monitors], [Disable xenstat and xentop monitoring tools]) AX_ARG_DEFAULT_DISABLE([xenapi], [Enable Xen API Bindings]) AX_ARG_DEFAULT_ENABLE([ocamltools], [Disable Ocaml tools]) +AX_ARG_DEFAULT_ENABLE([xsmpolicy], [Disable XSM policy compilation]) AX_ARG_DEFAULT_DISABLE([miniterm], [Enable miniterm]) AX_ARG_DEFAULT_DISABLE([lomount], [Enable lomount]) AX_ARG_DEFAULT_DISABLE([ovmf], [Enable OVMF]) @@ -93,6 +95,14 @@ AS_IF([test "x$ocamltools" = "xy"], [ ocamltools="n" ]) ]) +AS_IF([test "x$xsmpolicy" = "xy"], [ + AC_PROG_CHECKPOLICY + AS_IF([test "x$CHECKPOLICY" = "xno"], [ + AS_IF([test "x$enable_xsmpolicy" = "xyes"], [ + AC_MSG_ERROR([XSM policy compilation enabled, but unable to find checkpolicy])]) + xsmpolicy="n" + ]) +]) AX_PATH_PROG_OR_FAIL([BASH], [bash]) AS_IF([echo "$PYTHON" | grep -q "^/"], [ PYTHONPATH=$PYTHON diff --git a/tools/flask/Makefile b/tools/flask/Makefile index add9035..bc77a06 100644 --- a/tools/flask/Makefile +++ b/tools/flask/Makefile @@ -1,8 +1,8 @@ XEN_ROOT = $(CURDIR)/../.. include $(XEN_ROOT)/tools/Rules.mk -SUBDIRS :-SUBDIRS += utils +SUBDIRS-y := utils +SUBDIRS-$(FLASK_POLICY) += policy .PHONY: all clean install all clean install: %: subdirs-% -- 1.8.1.2
Daniel De Graaf writes ("[Xen-devel] [PATCH 0/3] FLASK policy build rework"):> These patches update the example FLASK policy shipped with Xen and > enable its build if the required tools are present. The third patch > requires rerunning autoconf to update tools/configure. > > [PATCH 1/3] flask/policy: sort dom0 accesses > [PATCH 2/3] flask/policy: rework policy build system > [PATCH 3/3] tools/flask: add FLASK policy to buildApplied all three, thanks. Ian.