diff -r 7c771f0a24f3 -r dc417e6b868f .hgignore --- a/.hgignore Wed Jun 11 11:35:35 2008 +0100 +++ b/.hgignore Tue Jul 08 16:39:21 2008 -0400 @@ -182,7 +182,6 @@ ^tools/misc/xenperf$ ^tools/pygrub/build/.*$ ^tools/python/build/.*$ -^tools/python/xen/util/xsm/xsm\.py$ ^tools/security/secpol_tool$ ^tools/security/xen/.*$ ^tools/security/xensec_tool$ diff -r 7c771f0a24f3 -r dc417e6b868f tools/examples/xend-config.sxp --- a/tools/examples/xend-config.sxp Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/examples/xend-config.sxp Tue Jul 08 16:39:21 2008 -0400 @@ -14,6 +14,10 @@ #(logfile /var/log/xen/xend.log) #(loglevel DEBUG) +# Uncomment the line below. Set the value to flask, acm, or dummy to +# select a security module. + +#(xsm_module_name dummy) # The Xen-API server configuration. # diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/Makefile Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,284 @@ +# +# Makefile for the security policy. +# +# Targets: +# +# install - compile and install the policy configuration, and context files. +# 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'. +# + +######################################## +# +# 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 = 20 + +# Policy Type +# strict, targeted, +# strict-mls, targeted-mls, +# strict-mcs, targeted-mcs +TYPE = strict + +# Policy Name +# If set, this will be used as the policy +# name. Otherwise the policy type will be +# used for the name. +NAME = xenrefpolicy + +# Distribution +# Some distributions have portions of policy +# for programs or configurations specific to the +# distribution. Setting this will enable options +# for the distribution. +# redhat, gentoo, debian, and suse are current options. +# Fedora users should enable redhat. +#DISTRO = + +# Build monolithic policy. Putting n here +# will build a loadable module policy. +MONOLITHIC=y + +# Uncomment this to disable command echoing +#QUIET:=@ + +######################################## +# +# NO OPTIONS BELOW HERE +# + +# executable paths +PREFIX := /usr +BINDIR := $(PREFIX)/bin +SBINDIR := $(PREFIX)/sbin +CHECKPOLICY := $(BINDIR)/checkpolicy +CHECKMODULE := $(BINDIR)/checkmodule +SEMOD_PKG := $(BINDIR)/semodule_package +LOADPOLICY := $(SBINDIR)/flask-loadpolicy + +CFLAGS := -Wall + +# policy source layout +POLDIR := policy +MODDIR := $(POLDIR)/modules +FLASKDIR := $(POLDIR)/flask +SECCLASS := $(FLASKDIR)/security_classes +ISIDS := $(FLASKDIR)/initial_sids +AVS := $(FLASKDIR)/access_vectors + +#policy building support tools +SUPPORT := support +FCSORT := $(SUPPORT)/fc_sort.c + +# 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 +TOPDIR = $(DESTDIR)/etc/xen/ +INSTALLDIR = $(TOPDIR)/$(NAME) +SRCPATH = $(INSTALLDIR)/src +USERPATH = $(INSTALLDIR)/users +CONTEXTPATH = $(INSTALLDIR)/contexts + +# enable MLS if requested. +ifneq ($(findstring -mls,$(TYPE)),) + override M4PARAM += -D enable_mls + CHECKPOLICY += -M + CHECKMODULE += -M +endif + +# enable MLS if MCS requested. +ifneq ($(findstring -mcs,$(TYPE)),) + override M4PARAM += -D enable_mcs + CHECKPOLICY += -M + CHECKMODULE += -M +endif + +# compile targeted policy if requested. +ifneq ($(findstring targeted,$(TYPE)),) + override M4PARAM += -D targeted_policy +endif + +# enable distribution-specific policy +ifneq ($(DISTRO),) + override M4PARAM += -D distro_$(DISTRO) +endif + +ifneq ($(OUTPUT_POLICY),) + CHECKPOLICY += -c $(OUTPUT_POLICY) +endif + +ifeq ($(NAME),) + NAME := $(TYPE) +endif + +# determine the policy version and current kernel version if possible +PV := $(shell $(CHECKPOLICY) -V |cut -f 1 -d ' ') +KV := $(shell cat /selinux/policyvers) + +# dont print version warnings if we are unable to determine +# the currently running kernel's policy version +ifeq ($(KV),) + KV := $(PV) +endif + +FC := file_contexts +POLVER := policy.$(PV) + +M4SUPPORT = $(wildcard $(POLDIR)/support/*.spt) + +APPCONF := config/appconfig-$(TYPE) +APPDIR := $(CONTEXTPATH) +APPFILES := $(addprefix $(APPDIR)/,default_contexts default_type initrc_context failsafe_context userhelper_context removable_context dbus_contexts customizable_types) $(CONTEXTPATH)/files/media $(INSTALLDIR)/booleans +CONTEXTFILES += $(wildcard $(APPCONF)/*_context*) $(APPCONF)/media +USER_FILES := $(POLDIR)/systemuser $(POLDIR)/users + +ALL_LAYERS := $(filter-out $(MODDIR)/CVS,$(shell find $(wildcard $(MODDIR)/*) -maxdepth 0 -type d)) + +GENERATED_TE := $(basename $(foreach dir,$(ALL_LAYERS),$(wildcard $(dir)/*.te.in))) +GENERATED_IF := $(basename $(foreach dir,$(ALL_LAYERS),$(wildcard $(dir)/*.if.in))) +GENERATED_FC := $(basename $(foreach dir,$(ALL_LAYERS),$(wildcard $(dir)/*.fc.in))) + +# 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)) $(GENERATED_TE)) + +# modules.conf setting for base module +MODBASE := base + +# modules.conf setting for module +MODMOD := module + +# extract settings from modules.conf +BASE_MODS := $(foreach mod,$(shell awk '/^[[:blank:]]*[[:alpha:]]/{ if ($$3 == "$(MODBASE)") print $$1 }' $(MOD_CONF) 2> /dev/null),$(subst ./,,$(shell find -iname $(mod).te))) +MOD_MODS := $(foreach mod,$(shell awk '/^[[:blank:]]*[[:alpha:]]/{ if ($$3 == "$(MODMOD)") print $$1 }' $(MOD_CONF) 2> /dev/null),$(subst ./,,$(shell find -iname $(mod).te))) + +HOMEDIR_TEMPLATE = tmp/homedir_template + +######################################## +# +# Load appropriate rules +# + +ifeq ($(MONOLITHIC),y) + include Rules.monolithic +else + include Rules.modular +endif + +######################################## +# +# Create config files +# +conf: $(MOD_CONF) $(BOOLEANS) $(GENERATED_TE) $(GENERATED_IF) $(GENERATED_FC) + +$(MOD_CONF) $(BOOLEANS): $(POLXML) + @echo "Updating $(MOD_CONF) and $(BOOLEANS)" + $(QUIET) cd $(DOCS) && ../$(GENDOC) -t ../$(BOOLEANS) -m ../$(MOD_CONF) -x ../$(POLXML) + +######################################## +# +# Generate the fc_sort program +# +$(fcsort) : $(support)/fc_sort.c + $(verbose) $(CC) $(CFLAGS) $^ -o $@ + +######################################## +# +# Runtime binary policy patching of users +# +$(USERPATH)/system.users: $(M4SUPPORT) tmp/generated_definitions.conf $(USER_FILES) + @mkdir -p $(USERPATH) + @echo "Installing system.users" + @echo "# " > tmp/system.users + @echo "# Do not edit this file. " >> tmp/system.users + @echo "# This file is replaced on reinstalls of this policy." >> tmp/system.users + @echo "# Please edit local.users to make local changes." >> tmp/system.users + @echo "#" >> tmp/system.users + $(QUIET) m4 -D self_contained_policy $(M4PARAM) $^ | \ + egrep -v "^[[:blank:]]*($$|#)" | \ + sed -r -e 's/^[[:blank:]]+//' >> tmp/system.users + $(QUIET) install -m 644 tmp/system.users $@ + +$(USERPATH)/local.users: config/local.users + @mkdir -p $(USERPATH) + @echo "Installing local.users" + $(QUIET) install -b -m 644 $< $@ + +######################################## +# +# Appconfig files +# +install-appconfig: $(APPFILES) + +$(INSTALLDIR)/booleans: $(BOOLEANS) + @mkdir -p $(INSTALLDIR) + $(QUIET) egrep '^[[:blank:]]*[[:alpha:]]' $(BOOLEANS) \ + | sed -e 's/false/0/g' -e 's/true/1/g' > tmp/booleans + $(QUIET) install -m 644 tmp/booleans $@ + +$(CONTEXTPATH)/files/media: $(APPCONF)/media + @mkdir -p $(CONTEXTPATH)/files/ + $(QUIET) install -m 644 $< $@ + +$(APPDIR)/default_contexts: $(APPCONF)/default_contexts + @mkdir -p $(APPDIR) + $(QUIET) install -m 644 $< $@ + +$(APPDIR)/removable_context: $(APPCONF)/removable_context + @mkdir -p $(APPDIR) + $(QUIET) install -m 644 $< $@ + +$(APPDIR)/customizable_types: policy.conf + @mkdir -p $(APPDIR) + $(QUIET) grep "^type .*customizable" $< | cut -d',' -f1 | cut -d' ' -f2 > tmp/customizable_types + $(QUIET) install -m 644 tmp/customizable_types $@ + +$(APPDIR)/default_type: $(APPCONF)/default_type + @mkdir -p $(APPDIR) + $(QUIET) install -m 644 $< $@ + +######################################## +# +# Install policy sources +# +install-src: + rm -rf $(SRCPATH)/policy.old + -mv $(SRCPATH)/policy $(SRCPATH)/policy.old + mkdir -p $(SRCPATH)/policy + cp -R . $(SRCPATH)/policy + +######################################## +# +# Clean everything +# +bare: clean + rm -f $(POLXML) + rm -f $(SUPPORT)/*.pyc + rm -f $(FCSORT) + rm -f $(MOD_CONF) + rm -f $(BOOLEANS) + rm -fR $(HTMLDIR) +ifneq ($(GENERATED_TE),) + rm -f $(GENERATED_TE) +endif +ifneq ($(GENERATED_IF),) + rm -f $(GENERATED_IF) +endif +ifneq ($(GENERATED_FC),) + rm -f $(GENERATED_FC) +endif + +.PHONY: install-src install-appconfig conf html bare diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/Rules.modular --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/Rules.modular Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,166 @@ +######################################## +# +# Rules and Targets for building modular policies +# + +ALL_MODULES := $(filter $(BASE_MODS) $(MOD_MODS),$(DETECTED_MODS)) +ALL_INTERFACES := $(ALL_MODULES:.te=.if) + +BASE_PKG := base.pp +BASE_FC := base.fc + +BASE_SECTIONS := tmp/pre_te_files.conf tmp/generated_definitions.conf tmp/all_interfaces.conf tmp/all_attrs_types.conf $(GLOBALBOOL) $(GLOBALTUN) tmp/only_te_rules.conf tmp/all_post.conf + +BASE_PRE_TE_FILES := $(SECCLASS) $(ISIDS) $(AVS) $(M4SUPPORT) $(POLDIR)/mls $(POLDIR)/mcs +BASE_TE_FILES := $(BASE_MODS) +BASE_POST_TE_FILES := $(POLDIR)/systemuser $(POLDIR)/constraints +BASE_FC_FILES := $(BASE_MODS:.te=.fc) + +MOD_MODULES := $(MOD_MODS:.te=.mod) +MOD_PKGS := $(notdir $(MOD_MODS:.te=.pp)) + +# search layer dirs for source files +vpath %.te $(ALL_LAYERS) +vpath %.if $(ALL_LAYERS) +vpath %.fc $(ALL_LAYERS) + +######################################## +# +# default action: create all module packages +# +default: base + +base: $(BASE_PKG) + +modules: $(MOD_PKGS) + +#policy: $(POLVER) +#install: $(LOADPATH) $(FCPATH) $(APPFILES) $(USERPATH)/local.users +#load: tmp/load + +######################################## +# +# Create a base module package +# +$(BASE_PKG): tmp/base.mod $(BASE_FC) + @echo "Creating $(NAME) base module package" + $(QUIET) $(SEMOD_PKG) $@ $^ + +######################################## +# +# Compile a base module +# +tmp/base.mod: base.conf + @echo "Compiling $(NAME) base module" + $(QUIET) $(CHECKMODULE) $^ -o $@ + +######################################## +# +# Construct a base module policy.conf +# +base.conf: $(BASE_SECTIONS) + @echo "Creating $(NAME) base module policy.conf" +# checkpolicy can use the #line directives provided by -s for error reporting: + $(QUIET) m4 -D self_contained_policy $(M4PARAM) -s $^ > tmp/$@.tmp + $(QUIET) sed -e /^portcon/d -e /^nodecon/d -e /^netifcon/d < tmp/$@.tmp > $@ +# the ordering of these ocontexts matters: + $(QUIET) grep ^portcon tmp/$@.tmp >> $@ || true + $(QUIET) grep ^netifcon tmp/$@.tmp >> $@ || true + $(QUIET) grep ^nodecon tmp/$@.tmp >> $@ || true + +tmp/pre_te_files.conf: $(BASE_PRE_TE_FILES) + @test -d tmp || mkdir -p tmp + $(QUIET) cat $^ > $@ + +tmp/generated_definitions.conf: $(ALL_LAYERS) $(BASE_TE_FILES) + @test -d tmp || mkdir -p tmp +# define all available object classes + $(QUIET) $(GENPERM) $(AVS) $(SECCLASS) > $@ +# per-userdomain templates + $(QUIET) echo "define(\`per_userdomain_templates',\`" >> $@ + $(QUIET) for i in $(patsubst %.te,%,$(notdir $(ALL_MODULES))); do \ + echo "ifdef(\`""$$i""_per_userdomain_template',\`""$$i""_per_userdomain_template("'$$*'")')" \ + >> $@ ;\ + done + $(QUIET) echo "')" >> $@ +# define foo.te + $(QUIET) for i in $(notdir $(BASE_TE_FILES)); do \ + echo "define(\`$$i')" >> $@ ;\ + done + $(QUIET) $(SETTUN) $(BOOLEANS) >> $@ + +tmp/all_interfaces.conf: $(M4SUPPORT) $(ALL_INTERFACES) +ifeq ($(ALL_INTERFACES),) + $(error No enabled modules! $(notdir $(MOD_CONF)) may need to be generated by using "make conf") +endif + @test -d tmp || mkdir -p tmp + $(QUIET) m4 $^ | sed -e s/dollarsstar/\$$\*/g > $@ + +tmp/all_te_files.conf: $(BASE_TE_FILES) +ifeq ($(BASE_TE_FILES),) + $(error No enabled modules! $(notdir $(MOD_CONF)) may need to be generated by using "make conf") +endif + @test -d tmp || mkdir -p tmp + $(QUIET) cat $^ > $@ + +tmp/post_te_files.conf: $(BASE_POST_TE_FILES) + @test -d tmp || mkdir -p tmp + $(QUIET) cat $^ > $@ + +# extract attributes and put them first. extract post te stuff +# like genfscon and put last. portcon, nodecon, and netifcon +# is delayed since they are generated by m4 +tmp/all_attrs_types.conf tmp/only_te_rules.conf tmp/all_post.conf: tmp/all_te_files.conf tmp/post_te_files.conf + $(QUIET) grep ^attribute tmp/all_te_files.conf > tmp/all_attrs_types.conf || true + $(QUIET) grep '^type ' tmp/all_te_files.conf >> tmp/all_attrs_types.conf + $(QUIET) cat tmp/post_te_files.conf > tmp/all_post.conf + $(QUIET) grep '^sid ' tmp/all_te_files.conf >> tmp/all_post.conf || true + $(QUIET) egrep '^fs_use_(xattr|task|trans)' tmp/all_te_files.conf >> tmp/all_post.conf || true + $(QUIET) grep ^genfscon tmp/all_te_files.conf >> tmp/all_post.conf || true + $(QUIET) sed -r -e /^attribute/d -e '/^type /d' -e /^genfscon/d \ + -e '/^sid /d' -e '/^fs_use_(xattr|task|trans)/d' \ + < tmp/all_te_files.conf > tmp/only_te_rules.conf + +######################################## +# +# Construct base module file contexts +# +$(BASE_FC): $(M4SUPPORT) tmp/generated_definitions.conf $(BASE_FC_FILES) $(FCSORT) +ifeq ($(BASE_FC_FILES),) + $(error No enabled modules! $(notdir $(MOD_CONF)) may need to be generated by using "make conf") +endif + @echo "Creating $(NAME) base module file contexts." + @test -d tmp || mkdir -p tmp + $(QUIET) m4 $(M4PARAM) $(M4SUPPORT) tmp/generated_definitions.conf $(BASE_FC_FILES) > tmp/$@.tmp + $(QUIET) grep -e HOME -e ROLE tmp/$@.tmp > $(HOMEDIR_TEMPLATE) + $(QUIET) sed -i -e /HOME/d -e /ROLE/d tmp/$@.tmp + $(QUIET) $(FCSORT) tmp/$@.tmp $@ + +######################################## +# +# Build module packages +# +tmp/%.mod: $(M4SUPPORT) tmp/generated_definitions.conf tmp/all_interfaces.conf %.te + @if test -z "$(filter $^,$(MOD_MODS))"; then \ + echo "The $(notdir $(basename $@)) module is not configured to be compiled as a lodable module." ;\ + false ;\ + fi + @echo "Compliling $(NAME) $(@F) module" + $(QUIET) m4 $(M4PARAM) -s $^ > $(@:.mod=.tmp) + $(QUIET) $(CHECKMODULE) -m $(@:.mod=.tmp) -o $@ + +%.pp: tmp/%.mod %.fc + @echo "Creating $(NAME) $(@F) policy package" + $(QUIET) $(SEMOD_PKG) $@ $^ + +######################################## +# +# Clean the sources +# +clean: + rm -fR tmp + rm -f base.conf + rm -f *.pp + rm -f $(BASE_FC) + +.PHONY: default base modules clean diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/Rules.monolithic --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/Rules.monolithic Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,225 @@ +######################################## +# +# Rules and Targets for building monolithic policies +# + +# install paths +POLICYPATH = $(INSTALLDIR)/policy +LOADPATH = $(POLICYPATH)/$(POLVER) +FCPATH = $(CONTEXTPATH)/files/file_contexts +HOMEDIRPATH = $(CONTEXTPATH)/files/homedir_template + +# for monolithic policy use all base and module to create policy +ENABLEMOD := $(BASE_MODS) $(MOD_MODS) + +ALL_MODULES := $(filter $(ENABLEMOD),$(DETECTED_MODS)) + +ALL_INTERFACES := $(ALL_MODULES:.te=.if) +ALL_TE_FILES := $(ALL_MODULES) +ALL_FC_FILES := $(ALL_MODULES:.te=.fc) + +PRE_TE_FILES := $(SECCLASS) $(ISIDS) $(AVS) $(M4SUPPORT) $(POLDIR)/mls $(POLDIR)/mcs +POST_TE_FILES := $(POLDIR)/systemuser $(POLDIR)/users $(POLDIR)/constraints + +POLICY_SECTIONS := tmp/pre_te_files.conf tmp/generated_definitions.conf tmp/all_interfaces.conf tmp/all_attrs_types.conf $(GLOBALBOOL) $(GLOBALTUN) tmp/only_te_rules.conf tmp/all_post.conf + +######################################## +# +# default action: build policy locally +# +default: policy + +policy: $(POLVER) + +install: $(LOADPATH) $(FCPATH) $(APPFILES) $(USERPATH)/local.users + +load: tmp/load + +######################################## +# +# Build a binary policy locally +# +$(POLVER): policy.conf + @echo "Compiling $(NAME) $(POLVER)" +ifneq ($(PV),$(KV)) + @echo + @echo "WARNING: Policy version mismatch! Is your OUTPUT_POLICY set correctly?" + @echo +endif + $(QUIET) $(CHECKPOLICY) $^ -o $@ + +######################################## +# +# Install a binary policy +# +$(LOADPATH): policy.conf + @mkdir -p $(POLICYPATH) + @echo "Compiling and installing $(NAME) $(LOADPATH)" +ifneq ($(PV),$(KV)) + @echo + @echo "WARNING: Policy version mismatch! Is your OUTPUT_POLICY set correctly?" + @echo +endif + $(QUIET) $(CHECKPOLICY) $^ -o $@ + +######################################## +# +# Load the binary policy +# +reload tmp/load: $(LOADPATH) $(FCPATH) + @echo "Loading $(NAME) $(LOADPATH)" + $(QUIET) $(LOADPOLICY) -q $(LOADPATH) + @touch tmp/load + +######################################## +# +# 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 $^ > tmp/$@.tmp + $(QUIET) sed -e /^portcon/d -e /^nodecon/d -e /^netifcon/d < tmp/$@.tmp > $@ +# the ordering of these ocontexts matters: + $(QUIET) grep ^portcon tmp/$@.tmp >> $@ || true + $(QUIET) grep ^netifcon tmp/$@.tmp >> $@ || true + $(QUIET) grep ^nodecon tmp/$@.tmp >> $@ || true + +tmp/pre_te_files.conf: $(PRE_TE_FILES) + @test -d tmp || mkdir -p tmp + $(QUIET) cat $^ > $@ + +tmp/generated_definitions.conf: $(ALL_LAYERS) $(ALL_TE_FILES) +# per-userdomain templates: + @test -d tmp || mkdir -p tmp + $(QUIET) echo "define(\`per_userdomain_templates',\`" > $@ + $(QUIET) for i in $(patsubst %.te,%,$(notdir $(ALL_MODULES))); do \ + echo "ifdef(\`""$$i""_per_userdomain_template',\`""$$i""_per_userdomain_template("'$$*'")')" \ + >> $@ ;\ + done + $(QUIET) echo "')" >> $@ +# define foo.te + $(QUIET) for i in $(notdir $(ALL_MODULES)); do \ + echo "define(\`$$i')" >> $@ ;\ + done +# $(QUIET) $(SETTUN) $(BOOLEANS) >> $@ + +tmp/all_interfaces.conf: $(M4SUPPORT) $(ALL_INTERFACES) +ifeq ($(ALL_INTERFACES),) + $(error No enabled modules! $(notdir $(MOD_CONF)) may need to be generated by using "make conf") +endif + @test -d tmp || mkdir -p tmp + $(QUIET) m4 $^ | sed -e s/dollarsstar/\$$\*/g > $@ + +tmp/all_te_files.conf: $(ALL_TE_FILES) +ifeq ($(ALL_TE_FILES),) + $(error No enabled modules! $(notdir $(MOD_CONF)) may need to be generated by using "make conf") +endif + @test -d tmp || mkdir -p tmp + $(QUIET) cat $^ > $@ + +tmp/post_te_files.conf: $(POST_TE_FILES) + @test -d tmp || mkdir -p tmp + $(QUIET) cat $^ > $@ + +# extract attributes and put them first. extract post te stuff +# like genfscon and put last. portcon, nodecon, and netifcon +# is delayed since they are generated by m4 +tmp/all_attrs_types.conf tmp/only_te_rules.conf tmp/all_post.conf: tmp/all_te_files.conf tmp/post_te_files.conf + $(QUIET) grep ^attribute tmp/all_te_files.conf > tmp/all_attrs_types.conf || true + $(QUIET) grep '^type ' tmp/all_te_files.conf >> tmp/all_attrs_types.conf + $(QUIET) cat tmp/post_te_files.conf > tmp/all_post.conf + $(QUIET) grep '^sid ' tmp/all_te_files.conf >> tmp/all_post.conf || true + $(QUIET) egrep '^fs_use_(xattr|task|trans)' tmp/all_te_files.conf >> tmp/all_post.conf || true + $(QUIET) grep ^genfscon tmp/all_te_files.conf >> tmp/all_post.conf || true + $(QUIET) sed -r -e /^attribute/d -e '/^type /d' -e /^genfscon/d \ + -e '/^sid /d' -e '/^fs_use_(xattr|task|trans)/d' \ + < tmp/all_te_files.conf > tmp/only_te_rules.conf + +######################################## +# +# 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 + +######################################## +# +# Construct file_contexts +# +$(FC): $(M4SUPPORT) tmp/generated_definitions.conf $(ALL_FC_FILES) $(FCSORT) +ifeq ($(ALL_FC_FILES),) + $(error No enabled modules! $(notdir $(MOD_CONF)) may need to be generated by using "make conf") +endif + @echo "Creating $(NAME) file_contexts." + @test -d tmp || mkdir -p tmp + $(QUIET) m4 $(M4PARAM) $(M4SUPPORT) tmp/generated_definitions.conf $(ALL_FC_FILES) > tmp/$@.tmp + $(QUIET) grep -e HOME -e ROLE tmp/$@.tmp > $(HOMEDIR_TEMPLATE) + $(QUIET) sed -i -e /HOME/d -e /ROLE/d tmp/$@.tmp + $(QUIET) $(FCSORT) tmp/$@.tmp $@ + +######################################## +# +# Install file_contexts +# +$(FCPATH): $(FC) $(LOADPATH) $(USERPATH)/system.users + @echo "Validating $(NAME) file_contexts." + $(QUIET) $(SETFILES) -q -c $(LOADPATH) $(FC) + @echo "Installing file_contexts." + @mkdir -p $(CONTEXTPATH)/files + $(QUIET) install -m 644 $(FC) $(FCPATH) + $(QUIET) install -m 644 $(HOMEDIR_TEMPLATE) $(HOMEDIRPATH) + $(QUIET) $(GENHOMEDIRCON) -d $(TOPDIR) -t $(NAME) $(USEPWD) + +######################################## +# +# Filesystem labeling +# +FILESYSTEMS := `mount | grep -v "context=" | egrep -v '\((|.*,)bind(,.*|)\)' | awk '/(ext[23]| xfs| jfs).*rw/{print $$3}';` + +checklabels: $(FC) $(SETFILES) + @if test -z "$(FILESYSTEMS)"; then \ + echo "No filesystems with extended attributes found!" ;\ + false ;\ + fi + $(QUIET) $(SETFILES) -v -n $(FC) $(FILESYSTEMS) + +restorelabels: $(FC) $(SETFILES) + @if test -z "$(FILESYSTEMS)"; then \ + echo "No filesystems with extended attributes found!" ;\ + false ;\ + fi + $(QUIET) $(SETFILES) -v $(FC) $(FILESYSTEMS) + +relabel: $(FC) $(SETFILES) + @if test -z "$(FILESYSTEMS)"; then \ + echo "No filesystems with extended attributes found!" ;\ + false ;\ + fi + $(QUIET) $(SETFILES) $(FC) $(FILESYSTEMS) + +######################################## +# +# Run policy source checks +# +check: policy.conf $(FC) + $(SECHECK) -s --profile=development --policy=policy.conf --fcfile=$(FC) > $@.res + +longcheck: policy.conf $(FC) + $(SECHECK) -s --profile=all --policy=policy.conf --fcfile=$(FC) > $@.res + +######################################## +# +# Clean the sources +# +clean: + rm -fR tmp + rm -f policy.conf + rm -f policy.$(PV) + rm -f $(FC) + rm -f *.res + +.PHONY: default policy install load reload enableaudit checklabels restorelabels relabel check longcheck clean diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/constraints --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/constraints Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,27 @@ + +# +# Define the constraints +# +# constrain class_set perm_set expression ; +# +# expression : ( expression ) +# | not expression +# | expression and expression +# | expression or expression +# | u1 op u2 +# | r1 role_op r2 +# | t1 op t2 +# | u1 op names +# | u2 op names +# | r1 op names +# | r2 op names +# | t1 op names +# | t2 op names +# +# op : == | != +# role_op : == | != | eq | dom | domby | incomp +# +# names : name | { name_list } +# name_list : name | name_list name +# + diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/flask/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/flask/Makefile Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,41 @@ +# flask needs to know where to export the libselinux headers. +LIBSEL ?= ../../libselinux + +# flask needs to know where to export the kernel headers. +LINUXDIR ?= ../../../linux-2.6 + +AWK = awk + +CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ + else if [ -x /bin/bash ]; then echo /bin/bash; \ + else echo sh; fi ; fi) + +FLASK_H_DEPEND = security_classes initial_sids +AV_H_DEPEND = access_vectors + +FLASK_H_FILES = class_to_string.h flask.h initial_sid_to_string.h +AV_H_FILES = av_inherit.h common_perm_to_string.h av_perm_to_string.h av_permissions.h +ALL_H_FILES = $(FLASK_H_FILES) $(AV_H_FILES) + +all: $(ALL_H_FILES) + +$(FLASK_H_FILES): $(FLASK_H_DEPEND) + $(CONFIG_SHELL) mkflask.sh $(AWK) $(FLASK_H_DEPEND) + +$(AV_H_FILES): $(AV_H_DEPEND) + $(CONFIG_SHELL) mkaccess_vector.sh $(AWK) $(AV_H_DEPEND) + +tolib: all + install -m 644 flask.h av_permissions.h $(LIBSEL)/include/selinux + install -m 644 class_to_string.h av_inherit.h common_perm_to_string.h av_perm_to_string.h $(LIBSEL)/src + +tokern: all + install -m 644 $(ALL_H_FILES) $(LINUXDIR)/security/selinux/include + +install: all + +relabel: + +clean: + rm -f $(FLASK_H_FILES) + rm -f $(AV_H_FILES) diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/flask/access_vectors --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/flask/access_vectors Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,166 @@ +# +# Define common prefixes for access vectors +# +# common common_name { permission_name ... } + +# +# Define a common prefix for file access vectors. +# + + +# +# Define the access vectors. +# +# class class_name [ inherits common_name ] { permission_name ... } + + +# +# Define the access vector interpretation for file-related objects. +# + +class xen +{ + scheduler + 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 +} + +class domain +{ + setvcpucontext + pause + unpause + resume + create + transition + max_vcpus + destroy + setvcpuaffinity + getvcpuaffinity + scheduler + getdomaininfo + getvcpuinfo + getvcpucontext + setdomainmaxmem + setdomainhandle + setdebugging + hypercall + settime + set_target + shutdown + setaddrsize + getaddrsize + trigger + getextvcpucontext + setextvcpucontext +} + +class hvm +{ + sethvmc + gethvmc + setparam + getparam + pcilevel + irqlevel + pciroute + bind_irq + cacheattr +} + +class event +{ + bind + send + status + notify + create + vector + reset +} + +class grant +{ + map_read + map_write + unmap + transfer + setup + copy + query +} + +class mmu +{ + map_read + map_write + pageinfo + pagelist + adjust + stat + translategp + updatemp + physmap + pinpage + mfnlist + memorymap +} + +class shadow +{ + disable + enable + logdirty +} + +class resource +{ + add + remove + use + add_irq + remove_irq + add_ioport + remove_ioport + add_iomem + remove_iomem + stat_device + add_device + remove_device +} + +class security +{ + compute_av + compute_create + compute_member + check_context + load_policy + compute_relabel + compute_user + setenforce + setbool + setsecparam +} diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/flask/initial_sids --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/flask/initial_sids Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,17 @@ +# FLASK + +# +# Define initial security identifiers +# +sid xen +sid dom0 +sid domU +sid domio +sid domxen +sid unlabeled +sid security +sid ioport +sid iomem +sid pirq +sid device +# FLASK diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/flask/mkaccess_vector.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/flask/mkaccess_vector.sh Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,227 @@ +#!/bin/sh - +# + +# FLASK + +set -e + +awk=$1 +shift + +# output files +av_permissions="av_permissions.h" +av_inherit="av_inherit.h" +common_perm_to_string="common_perm_to_string.h" +av_perm_to_string="av_perm_to_string.h" + +cat $* | $awk " +BEGIN { + outfile = \"$av_permissions\" + inheritfile = \"$av_inherit\" + cpermfile = \"$common_perm_to_string\" + avpermfile = \"$av_perm_to_string\" + "' + nextstate = "COMMON_OR_AV"; + printf("/* This file is automatically generated. Do not edit. */\n") > outfile; + printf("/* This file is automatically generated. Do not edit. */\n") > inheritfile; + printf("/* This file is automatically generated. Do not edit. */\n") > cpermfile; + printf("/* This file is automatically generated. Do not edit. */\n") > avpermfile; +; + } +/^[ \t]*#/ { + next; + } +$1 == "common" { + if (nextstate != "COMMON_OR_AV") + { + printf("Parse error: Unexpected COMMON definition on line %d\n", NR); + next; + } + + if ($2 in common_defined) + { + printf("Duplicate COMMON definition for %s on line %d.\n", $2, NR); + next; + } + common_defined[$2] = 1; + + tclass = $2; + common_name = $2; + permission = 1; + + printf("TB_(common_%s_perm_to_string)\n", $2) > cpermfile; + + nextstate = "COMMON-OPENBRACKET"; + next; + } +$1 == "class" { + if (nextstate != "COMMON_OR_AV" && + nextstate != "CLASS_OR_CLASS-OPENBRACKET") + { + printf("Parse error: Unexpected class definition on line %d\n", NR); + next; + } + + tclass = $2; + + if (tclass in av_defined) + { + printf("Duplicate access vector definition for %s on line %d\n", tclass, NR); + next; + } + av_defined[tclass] = 1; + + inherits = ""; + permission = 1; + + nextstate = "INHERITS_OR_CLASS-OPENBRACKET"; + next; + } +$1 == "inherits" { + if (nextstate != "INHERITS_OR_CLASS-OPENBRACKET") + { + printf("Parse error: Unexpected INHERITS definition on line %d\n", NR); + next; + } + + if (!($2 in common_defined)) + { + printf("COMMON %s is not defined (line %d).\n", $2, NR); + next; + } + + inherits = $2; + permission = common_base[$2]; + + for (combined in common_perms) + { + split(combined,separate, SUBSEP); + if (separate[1] == inherits) + { + inherited_perms[common_perms[combined]] = separate[2]; + } + } + + j = 1; + for (i in inherited_perms) { + ind[j] = i + 0; + j++; + } + n = asort(ind); + for (i = 1; i <= n; i++) { + perm = inherited_perms[ind[i]]; + printf("#define %s__%s", toupper(tclass), toupper(perm)) > outfile; + spaces = 40 - (length(perm) + length(tclass)); + if (spaces < 1) + spaces = 1; + for (j = 0; j < spaces; j++) + printf(" ") > outfile; + printf("0x%08xUL\n", ind[i]) > outfile; + } + printf("\n") > outfile; + for (i in ind) delete ind[i]; + for (i in inherited_perms) delete inherited_perms[i]; + + printf(" S_(SECCLASS_%s, %s, 0x%08xUL)\n", toupper(tclass), inherits, permission) > inheritfile; + + nextstate = "CLASS_OR_CLASS-OPENBRACKET"; + next; + } +$1 == "{" { + if (nextstate != "INHERITS_OR_CLASS-OPENBRACKET" && + nextstate != "CLASS_OR_CLASS-OPENBRACKET" && + nextstate != "COMMON-OPENBRACKET") + { + printf("Parse error: Unexpected { on line %d\n", NR); + next; + } + + if (nextstate == "INHERITS_OR_CLASS-OPENBRACKET") + nextstate = "CLASS-CLOSEBRACKET"; + + if (nextstate == "CLASS_OR_CLASS-OPENBRACKET") + nextstate = "CLASS-CLOSEBRACKET"; + + if (nextstate == "COMMON-OPENBRACKET") + nextstate = "COMMON-CLOSEBRACKET"; + } +/[a-z][a-z_]*/ { + if (nextstate != "COMMON-CLOSEBRACKET" && + nextstate != "CLASS-CLOSEBRACKET") + { + printf("Parse error: Unexpected symbol %s on line %d\n", $1, NR); + next; + } + + if (nextstate == "COMMON-CLOSEBRACKET") + { + if ((common_name,$1) in common_perms) + { + printf("Duplicate permission %s for common %s on line %d.\n", $1, common_name, NR); + next; + } + + common_perms[common_name,$1] = permission; + + printf("#define COMMON_%s__%s", toupper(common_name), toupper($1)) > outfile; + + printf(" S_(\"%s\")\n", $1) > cpermfile; + } + else + { + if ((tclass,$1) in av_perms) + { + printf("Duplicate permission %s for %s on line %d.\n", $1, tclass, NR); + next; + } + + av_perms[tclass,$1] = permission; + + if (inherits != "") + { + if ((inherits,$1) in common_perms) + { + printf("Permission %s in %s on line %d conflicts with common permission.\n", $1, tclass, inherits, NR); + next; + } + } + + printf("#define %s__%s", toupper(tclass), toupper($1)) > outfile; + + printf(" S_(SECCLASS_%s, %s__%s, \"%s\")\n", toupper(tclass), toupper(tclass), toupper($1), $1) > avpermfile; + } + + spaces = 40 - (length($1) + length(tclass)); + if (spaces < 1) + spaces = 1; + + for (i = 0; i < spaces; i++) + printf(" ") > outfile; + printf("0x%08xUL\n", permission) > outfile; + permission = permission * 2; + } +$1 == "}" { + if (nextstate != "CLASS-CLOSEBRACKET" && + nextstate != "COMMON-CLOSEBRACKET") + { + printf("Parse error: Unexpected } on line %d\n", NR); + next; + } + + if (nextstate == "COMMON-CLOSEBRACKET") + { + common_base[common_name] = permission; + printf("TE_(common_%s_perm_to_string)\n\n", common_name) > cpermfile; + } + + printf("\n") > outfile; + + nextstate = "COMMON_OR_AV"; + } +END { + if (nextstate != "COMMON_OR_AV" && nextstate != "CLASS_OR_CLASS-OPENBRACKET") + printf("Parse error: Unexpected end of file\n"); + + }' + +# FLASK diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/flask/mkflask.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/flask/mkflask.sh Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,95 @@ +#!/bin/sh - +# + +# FLASK + +set -e + +awk=$1 +shift 1 + +# output file +output_file="flask.h" +debug_file="class_to_string.h" +debug_file2="initial_sid_to_string.h" + +cat $* | $awk " +BEGIN { + outfile = \"$output_file\" + debugfile = \"$debug_file\" + debugfile2 = \"$debug_file2\" + "' + nextstate = "CLASS"; + + printf("/* This file is automatically generated. Do not edit. */\n") > outfile; + + printf("#ifndef _SELINUX_FLASK_H_\n") > outfile; + printf("#define _SELINUX_FLASK_H_\n") > outfile; + printf("\n/*\n * Security object class definitions\n */\n") > outfile; + printf("/* This file is automatically generated. Do not edit. */\n") > debugfile; + printf("/*\n * Security object class definitions\n */\n") > debugfile; + printf(" S_(\"null\")\n") > debugfile; + printf("/* This file is automatically generated. Do not edit. */\n") > debugfile2; + printf("static char *initial_sid_to_string[] =\n{\n") > debugfile2; + printf(" \"null\",\n") > debugfile2; + } +/^[ \t]*#/ { + next; + } +$1 == "class" { + if (nextstate != "CLASS") + { + printf("Parse error: Unexpected class definition on line %d\n", NR); + next; + } + + if ($2 in class_found) + { + printf("Duplicate class definition for %s on line %d.\n", $2, NR); + next; + } + class_found[$2] = 1; + + class_value++; + + printf("#define SECCLASS_%s", toupper($2)) > outfile; + for (i = 0; i < 40 - length($2); i++) + printf(" ") > outfile; + printf("%d\n", class_value) > outfile; + + printf(" S_(\"%s\")\n", $2) > debugfile; + } +$1 == "sid" { + if (nextstate == "CLASS") + { + nextstate = "SID"; + printf("\n/*\n * Security identifier indices for initial entities\n */\n") > outfile; + } + + if ($2 in sid_found) + { + printf("Duplicate SID definition for %s on line %d.\n", $2, NR); + next; + } + sid_found[$2] = 1; + sid_value++; + + printf("#define SECINITSID_%s", toupper($2)) > outfile; + for (i = 0; i < 37 - length($2); i++) + printf(" ") > outfile; + printf("%d\n", sid_value) > outfile; + printf(" \"%s\",\n", $2) > debugfile2; + } +END { + if (nextstate != "SID") + printf("Parse error: Unexpected end of file\n"); + + printf("\n#define SECINITSID_NUM") > outfile; + for (i = 0; i < 34; i++) + printf(" ") > outfile; + printf("%d\n", sid_value) > outfile; + printf("\n#endif\n") > outfile; + printf("};\n\n") > debugfile2; + }' + +# FLASK diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/flask/security_classes --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/flask/security_classes Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,20 @@ +# FLASK + +# +# Define the security object classes +# + +# Classes marked as userspace are classes +# for userspace object managers + +class xen +class domain +class hvm +class mmu +class resource +class shadow +class event +class grant +class security + +# FLASK diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/global_booleans --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/global_booleans Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,5 @@ +# +# 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 -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/global_tunables --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/global_tunables Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,6 @@ +# +# This file is for the declaration of global tunables. +# To change the default value at build time, the booleans.conf +# file should be used. +# + diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/mcs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/mcs Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,324 @@ +ifdef(`enable_mcs',` +# +# Define sensitivities +# +# Each sensitivity has a name and zero or more aliases. +# +# MCS is single-sensitivity. +# +sensitivity s0; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; +category c1; +category c2; +category c3; +category c4; +category c5; +category c6; +category c7; +category c8; +category c9; +category c10; +category c11; +category c12; +category c13; +category c14; +category c15; +category c16; +category c17; +category c18; +category c19; +category c20; +category c21; +category c22; +category c23; +category c24; +category c25; +category c26; +category c27; +category c28; +category c29; +category c30; +category c31; +category c32; +category c33; +category c34; +category c35; +category c36; +category c37; +category c38; +category c39; +category c40; +category c41; +category c42; +category c43; +category c44; +category c45; +category c46; +category c47; +category c48; +category c49; +category c50; +category c51; +category c52; +category c53; +category c54; +category c55; +category c56; +category c57; +category c58; +category c59; +category c60; +category c61; +category c62; +category c63; +category c64; +category c65; +category c66; +category c67; +category c68; +category c69; +category c70; +category c71; +category c72; +category c73; +category c74; +category c75; +category c76; +category c77; +category c78; +category c79; +category c80; +category c81; +category c82; +category c83; +category c84; +category c85; +category c86; +category c87; +category c88; +category c89; +category c90; +category c91; +category c92; +category c93; +category c94; +category c95; +category c96; +category c97; +category c98; +category c99; +category c100; +category c101; +category c102; +category c103; +category c104; +category c105; +category c106; +category c107; +category c108; +category c109; +category c110; +category c111; +category c112; +category c113; +category c114; +category c115; +category c116; +category c117; +category c118; +category c119; +category c120; +category c121; +category c122; +category c123; +category c124; +category c125; +category c126; +category c127; +category c128; +category c129; +category c130; +category c131; +category c132; +category c133; +category c134; +category c135; +category c136; +category c137; +category c138; +category c139; +category c140; +category c141; +category c142; +category c143; +category c144; +category c145; +category c146; +category c147; +category c148; +category c149; +category c150; +category c151; +category c152; +category c153; +category c154; +category c155; +category c156; +category c157; +category c158; +category c159; +category c160; +category c161; +category c162; +category c163; +category c164; +category c165; +category c166; +category c167; +category c168; +category c169; +category c170; +category c171; +category c172; +category c173; +category c174; +category c175; +category c176; +category c177; +category c178; +category c179; +category c180; +category c181; +category c182; +category c183; +category c184; +category c185; +category c186; +category c187; +category c188; +category c189; +category c190; +category c191; +category c192; +category c193; +category c194; +category c195; +category c196; +category c197; +category c198; +category c199; +category c200; +category c201; +category c202; +category c203; +category c204; +category c205; +category c206; +category c207; +category c208; +category c209; +category c210; +category c211; +category c212; +category c213; +category c214; +category c215; +category c216; +category c217; +category c218; +category c219; +category c220; +category c221; +category c222; +category c223; +category c224; +category c225; +category c226; +category c227; +category c228; +category c229; +category c230; +category c231; +category c232; +category c233; +category c234; +category c235; +category c236; +category c237; +category c238; +category c239; +category c240; +category c241; +category c242; +category c243; +category c244; +category c245; +category c246; +category c247; +category c248; +category c249; +category c250; +category c251; +category c252; +category c253; +category c254; +category c255; + + +# +# Each MCS level specifies a sensitivity and zero or more categories which may +# be associated with that sensitivity. +# +level s0:c0.c255; + +# +# Define the MCS policy +# +# mlsconstrain class_set perm_set expression ; +# +# mlsvalidatetrans class_set expression ; +# +# expression : ( expression ) +# | not expression +# | expression and expression +# | expression or expression +# | u1 op u2 +# | r1 role_mls_op r2 +# | t1 op t2 +# | l1 role_mls_op l2 +# | l1 role_mls_op h2 +# | h1 role_mls_op l2 +# | h1 role_mls_op h2 +# | l1 role_mls_op h1 +# | l2 role_mls_op h2 +# | u1 op names +# | u2 op names +# | r1 op names +# | r2 op names +# | t1 op names +# | t2 op names +# | u3 op names (NOTE: this is only available for mlsvalidatetrans) +# | r3 op names (NOTE: this is only available for mlsvalidatetrans) +# | t3 op names (NOTE: this is only available for mlsvalidatetrans) +# +# op : == | != +# role_mls_op : == | != | eq | dom | domby | incomp +# +# names : name | { name_list } +# name_list : name | name_list name +# + + +') dnl end enable_mcs diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/mls --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/mls Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,354 @@ + +ifdef(`enable_mls',` +# +# Define sensitivities +# +# Each sensitivity has a name and zero or more aliases. +# +sensitivity s0; +sensitivity s1; +sensitivity s2; +sensitivity s3; +sensitivity s4; +sensitivity s5; +sensitivity s6; +sensitivity s7; +sensitivity s8; +sensitivity s9; +sensitivity s10; +sensitivity s11; +sensitivity s12; +sensitivity s13; +sensitivity s14; +sensitivity s15; + +# +# Define the ordering of the sensitivity levels (least to greatest) +# +dominance { s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 } + + +# +# Define the categories +# +# Each category has a name and zero or more aliases. +# +category c0; +category c1; +category c2; +category c3; +category c4; +category c5; +category c6; +category c7; +category c8; +category c9; +category c10; +category c11; +category c12; +category c13; +category c14; +category c15; +category c16; +category c17; +category c18; +category c19; +category c20; +category c21; +category c22; +category c23; +category c24; +category c25; +category c26; +category c27; +category c28; +category c29; +category c30; +category c31; +category c32; +category c33; +category c34; +category c35; +category c36; +category c37; +category c38; +category c39; +category c40; +category c41; +category c42; +category c43; +category c44; +category c45; +category c46; +category c47; +category c48; +category c49; +category c50; +category c51; +category c52; +category c53; +category c54; +category c55; +category c56; +category c57; +category c58; +category c59; +category c60; +category c61; +category c62; +category c63; +category c64; +category c65; +category c66; +category c67; +category c68; +category c69; +category c70; +category c71; +category c72; +category c73; +category c74; +category c75; +category c76; +category c77; +category c78; +category c79; +category c80; +category c81; +category c82; +category c83; +category c84; +category c85; +category c86; +category c87; +category c88; +category c89; +category c90; +category c91; +category c92; +category c93; +category c94; +category c95; +category c96; +category c97; +category c98; +category c99; +category c100; +category c101; +category c102; +category c103; +category c104; +category c105; +category c106; +category c107; +category c108; +category c109; +category c110; +category c111; +category c112; +category c113; +category c114; +category c115; +category c116; +category c117; +category c118; +category c119; +category c120; +category c121; +category c122; +category c123; +category c124; +category c125; +category c126; +category c127; +category c128; +category c129; +category c130; +category c131; +category c132; +category c133; +category c134; +category c135; +category c136; +category c137; +category c138; +category c139; +category c140; +category c141; +category c142; +category c143; +category c144; +category c145; +category c146; +category c147; +category c148; +category c149; +category c150; +category c151; +category c152; +category c153; +category c154; +category c155; +category c156; +category c157; +category c158; +category c159; +category c160; +category c161; +category c162; +category c163; +category c164; +category c165; +category c166; +category c167; +category c168; +category c169; +category c170; +category c171; +category c172; +category c173; +category c174; +category c175; +category c176; +category c177; +category c178; +category c179; +category c180; +category c181; +category c182; +category c183; +category c184; +category c185; +category c186; +category c187; +category c188; +category c189; +category c190; +category c191; +category c192; +category c193; +category c194; +category c195; +category c196; +category c197; +category c198; +category c199; +category c200; +category c201; +category c202; +category c203; +category c204; +category c205; +category c206; +category c207; +category c208; +category c209; +category c210; +category c211; +category c212; +category c213; +category c214; +category c215; +category c216; +category c217; +category c218; +category c219; +category c220; +category c221; +category c222; +category c223; +category c224; +category c225; +category c226; +category c227; +category c228; +category c229; +category c230; +category c231; +category c232; +category c233; +category c234; +category c235; +category c236; +category c237; +category c238; +category c239; +category c240; +category c241; +category c242; +category c243; +category c244; +category c245; +category c246; +category c247; +category c248; +category c249; +category c250; +category c251; +category c252; +category c253; +category c254; +category c255; + + +# +# Each MLS level specifies a sensitivity and zero or more categories which may +# be associated with that sensitivity. +# +level s0:c0.c255; +level s1:c0.c255; +level s2:c0.c255; +level s3:c0.c255; +level s4:c0.c255; +level s5:c0.c255; +level s6:c0.c255; +level s7:c0.c255; +level s8:c0.c255; +level s9:c0.c255; +level s10:c0.c255; +level s11:c0.c255; +level s12:c0.c255; +level s13:c0.c255; +level s14:c0.c255; +level s15:c0.c255; + + +# +# Define the MLS policy +# +# mlsconstrain class_set perm_set expression ; +# +# mlsvalidatetrans class_set expression ; +# +# expression : ( expression ) +# | not expression +# | expression and expression +# | expression or expression +# | u1 op u2 +# | r1 role_mls_op r2 +# | t1 op t2 +# | l1 role_mls_op l2 +# | l1 role_mls_op h2 +# | h1 role_mls_op l2 +# | h1 role_mls_op h2 +# | l1 role_mls_op h1 +# | l2 role_mls_op h2 +# | u1 op names +# | u2 op names +# | r1 op names +# | r2 op names +# | t1 op names +# | t2 op names +# | u3 op names (NOTE: this is only available for mlsvalidatetrans) +# | r3 op names (NOTE: this is only available for mlsvalidatetrans) +# | t3 op names (NOTE: this is only available for mlsvalidatetrans) +# +# op : == | != +# role_mls_op : == | != | eq | dom | domby | incomp +# +# names : name | { name_list } +# name_list : name | name_list name +# + + +') dnl end enable_mls diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/modules.conf --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/modules.conf Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,21 @@ +# +# This file contains a listing of available modules. +# To prevent a module from being used in policy +# creation, set the module name to "off". +# +# For monolithic policies, modules set to "base" and "module" +# will be built into the policy. +# +# For modular policies, modules set to "base" will be +# included in the base module. "module" will be compiled +# as individual loadable modules. +# + +# Layer: xen +# Module: xen +# Required in base +# +# Policy for xen. +# +xen = base + diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/modules/xen/xen.te --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/modules/xen/xen.te Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,121 @@ +attribute xen_type; +attribute domain_type; +attribute resource_type; +attribute event_type; + +type xen_t, xen_type, domain_type; + +type dom0_t, domain_type; + +type domio_t, domain_type; + +type domxen_t, domain_type; + +type unlabeled_t, domain_type; + +type security_t, domain_type; + +type pirq_t, resource_type; +type ioport_t, resource_type; +type iomem_t, resource_type; +type device_t, resource_type; + +################################################################################ +# +# create_domain(priv_dom, domain) +# +################################################################################ +define(`create_domain', ` + type $2, domain_type; + allow $1 $2:domain {create max_vcpus setdomainmaxmem + setaddrsize getdomaininfo hypercall + setvcpucontext scheduler unpause + getvcpuinfo getvcpuaffinity}; + allow $1 $2:shadow {enable}; + allow $1 $2:mmu {map_read map_write memorymap adjust pinpage}; + allow $2 $2:mmu {map_read map_write pinpage}; + allow $2 domio_t:mmu {map_read}; + allow $2 $2:grant {query setup}; + allow $1 $2:grant {map_read unmap}; +') + +################################################################################ +# +# create_channel(caller, peer, channel) +# +################################################################################ +define(`create_channel', ` + type $3, event_type; + type_transition $1 $2:event $3; + allow $1 $3:event {create}; + allow $1 $3:event {bind}; +') + +allow dom0_t xen_t:xen {kexec readapic writeapic mtrr_read mtrr_add mtrr_del +scheduler physinfo heap quirk readconsole writeconsole settime microcode}; + +allow dom0_t domio_t:mmu {map_read map_write}; +allow dom0_t iomem_t:mmu {map_read map_write}; +allow dom0_t pirq_t:event {vector}; +allow dom0_t xen_t:mmu {memorymap}; + +allow dom0_t dom0_t:mmu {pinpage map_read map_write adjust}; +allow dom0_t dom0_t:grant {query setup}; +allow dom0_t dom0_t:domain {scheduler getdomaininfo getvcpuinfo getvcpuaffinity}; + +allow xen_t dom0_t:domain {create}; +allow xen_t dom0_t:resource {add remove}; +allow xen_t ioport_t:resource {add_ioport remove_ioport}; +allow dom0_t ioport_t:resource {use}; +allow xen_t iomem_t:resource {add_iomem remove_iomem}; +allow dom0_t iomem_t:resource {use}; +allow xen_t pirq_t:resource {add_irq remove_irq}; +allow dom0_t pirq_t:resource {use}; + +allow dom0_t security_t:security {compute_av compute_create compute_member +check_context load_policy compute_relabel compute_user setenforce setbool +setsecparam}; + +create_domain(dom0_t, domU_t) + +type evchn0-U_t, event_type; +type_transition dom0_t domU_t:event evchn0-U_t; +allow dom0_t evchn0-U_t:event {create}; +allow evchn0-U_t domU_t:event {bind}; +allow dom0_t evchn0-U_t:event {send}; + +type evchnU-0_t, event_type; +type_transition domU_t dom0_t:event evchnU-0_t; +allow dom0_t evchnU-0_t:event {create}; +allow domU_t evchnU-0_t:event {create}; +allow evchnU-0_t dom0_t:event {bind}; +allow domU_t evchnU-0_t:event {send}; + +type evchn0-0_t, event_type; +type_transition dom0_t dom0_t:event evchn0-0_t; +allow dom0_t evchn0-0_t:event {create}; +allow evchn0-0_t dom0_t:event {bind}; +allow dom0_t evchn0-0_t:event {send}; + +type evchnU-U_t, event_type; +type_transition domU_t domU_t:event evchnU-U_t; +allow domU_t evchnU-U_t:event {create}; +allow evchnU-U_t domU_t:event {bind}; +allow domU_t evchnU-U_t:event {send}; + +sid xen gen_context(system_u:system_r:xen_t,s0) +sid dom0 gen_context(system_u:system_r:dom0_t,s0) +sid domU gen_context(system_u:system_r:domU_t,s0) +sid domxen gen_context(system_u:system_r:domxen_t,s0) +sid domio gen_context(system_u:system_r:domio_t,s0) +sid unlabeled gen_context(system_u:system_r:unlabeled_t,s0) +sid security gen_context(system_u:system_r:security_t,s0) +sid pirq gen_context(system_u:object_r:pirq_t,s0) +sid iomem gen_context(system_u:object_r:iomem_t,s0) +sid ioport gen_context(system_u:object_r:ioport_t,s0) +sid device gen_context(system_u:object_r:device_t,s0) + +role system_r types { xen_type domain_type }; +role user_r types { xen_type domain_type }; +role sysadm_r types { xen_type domain_type }; +role staff_r types { xen_type domain_type }; diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/support/loadable_module.spt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/support/loadable_module.spt Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,166 @@ +######################################## +# +# Macros for switching between source policy +# and loadable policy module support +# + +############################## +# +# For adding the module statement +# +define(`policy_module',` + ifdef(`self_contained_policy',`',` + module $1 $2; + + require { + role system_r; + all_kernel_class_perms + } + ') +') + +############################## +# +# For use in interfaces, to optionally insert a require block +# +define(`gen_require',` + ifdef(`self_contained_policy',`',` + define(`in_gen_require_block') + require { + $1 + } + undefine(`in_gen_require_block') + ') +') + +############################## +# +# In the future interfaces should be in loadable modules +# +# template(name,rules) +# +define(`template',` + `define(`$1',` +##### begin $1(dollarsstar) + $2 +##### end $1(dollarsstar) + '') +') + +# helper function, since m4 wont expand macros +# if a line is a comment (#): +define(`policy_m4_comment',`dnl +##### $2 depth: $1 +')dnl + +############################## +# +# In the future interfaces should be in loadable modules +# +# interface(name,rules) +# +define(`interface',` + `define(`$1',` + + define(`policy_temp',incr(policy_call_depth)) + pushdef(`policy_call_depth',policy_temp) + undefine(`policy_temp') + + policy_m4_comment(policy_call_depth,begin `$1'(dollarsstar)) + + $2 + + define(`policy_temp',decr(policy_call_depth)) + pushdef(`policy_call_depth',policy_temp) + undefine(`policy_temp') + + policy_m4_comment(policy_call_depth,end `$1'(dollarsstar)) + + '') +') + +define(`policy_call_depth',0) + +############################## +# +# Optional policy handling +# +define(`optional_policy',` + ifdef(`self_contained_policy',` + ifdef(`$1',`$2',`$3') + ',` + optional { + $2 + ifelse(`$3',`',`',` + } else { + $3 + ') + } + ') +') + +############################## +# +# Determine if we should use the default +# tunable value as specified by the policy +# or if the override value should be used +# +define(`dflt_or_overr',`ifdef(`$1',$1,$2)') + +############################## +# +# Extract booleans out of an expression. +# This needs to be reworked so expressions +# with parentheses can work. + +define(`delcare_required_symbols',` +ifelse(regexp($1, `\w'), -1, `', `dnl +bool regexp($1, `\(\w+\)', `\1'); +delcare_required_symbols(regexp($1, `\w+\(.*\)', `\1'))dnl +') dnl +') + +############################## +# +# Tunable declaration +# +define(`gen_tunable',` + ifdef(`self_contained_policy',` + bool $1 dflt_or_overr(`$1'_conf,$2); + ',` + # loadable module tunable + # declaration will go here + # instead of bool when + # loadable modules support + # tunables + bool $1 dflt_or_overr(`$1'_conf,$2); + ') +') + +############################## +# +# Tunable policy handling +# +define(`tunable_policy',` + ifdef(`self_contained_policy',` + if (`$1') { + $2 + } else { + $3 + } + ',` + # structure for tunables + # will go here instead of a + # conditional when loadable + # modules support tunables + gen_require(` + delcare_required_symbols(`$1') + ') + + if (`$1') { + $2 + } else { + $3 + } + ') +') diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/support/misc_macros.spt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/support/misc_macros.spt Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,32 @@ + +######################################## +# +# Helper macros +# + +# +# shiftn(num,list...) +# +# shift the list num times +# +define(`shiftn',`ifelse($1,0,`shift($*)',`shiftn(decr($1),shift(shift($*)))')') + +######################################## +# +# gen_user(username, role_set, mls_defaultlevel, mls_range, [mcs_categories]) +# +define(`gen_user',`user $1 roles { $2 }`'ifdef(`enable_mls', ` level $3 range $4')`'ifdef(`enable_mcs',` level s0 range s0`'ifelse(`$5',,,` - s0:$5')');') + +######################################## +# +# gen_context(context,mls_sensitivity,[mcs_categories]) +# +define(`gen_context',`$1`'ifdef(`enable_mls',`:$2')`'ifdef(`enable_mcs',`:s0`'ifelse(`$3',,,`:$3')')') dnl + +######################################## +# +# gen_bool(name,default_value) +# +define(`gen_bool',` + bool $1 dflt_or_overr(`$1'_conf,$2); +') diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/systemuser --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/systemuser Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,19 @@ +################################## +# +# System User configuration. +# + +# +# gen_user(username, role_set, mls_defaultlevel, mls_range, [mcs_categories]) +# + +# +# system_u is the user identity for system processes and objects. +# There should be no corresponding Unix user identity for system, +# and a user process should never be assigned the system user +# identity. +# +gen_user(system_u, system_r, s0, s0 - s9:c0.c127, c0.c127) + +# Normal users should not be added to this file, +# but instead added to the users file. diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/policy/users --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/policy/users Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,39 @@ + +################################## +# +# Core User configuration. +# + +# +# gen_user(username, role_set, mls_defaultlevel, mls_range, [mcs_catetories]) +# + +# +# user_u is a generic user identity for Linux users who have no +# SELinux user identity defined. The modified daemons will use +# this user identity in the security context if there is no matching +# SELinux user identity for a Linux user. If you do not want to +# permit any access to such users, then remove this entry. +# +ifdef(`targeted_policy',` +gen_user(user_u, user_r sysadm_r system_r, s0, s0 - s9:c0.c127) +',` +gen_user(user_u, user_r, s0, s0 - s9:c0.c127) +') + +# +# The following users correspond to Unix identities. +# These identities are typically assigned as the user attribute +# when login starts the user shell. Users with access to the sysadm_r +# role should use the staff_r role instead of the user_r role when +# not in the sysadm_r. +# +ifdef(`targeted_policy',` + gen_user(root, user_r sysadm_r system_r, s0, s0 - s9:c0.c127, c0.c127) +',` + ifdef(`direct_sysadm_daemon',` + gen_user(root, sysadm_r staff_r system_r, s0, s0 - s9:c0.c127, c0.c127) + ',` + gen_user(root, sysadm_r staff_r, s0, s0 - s9:c0.c127, c0.c127) + ') +') diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/support/fc_sort.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/support/fc_sort.c Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,558 @@ +/* Copyright 2005, Tresys Technology + * + * Some parts of this came from matchpathcon.c in libselinux + */ + +/* PURPOSE OF THIS PROGRAM + * The original setfiles sorting algorithm did not take into + * account regular expression specificity. With the current + * strict and targeted policies this is not an issue because + * the file contexts are partially hand sorted and concatenated + * in the right order so that the matches are generally correct. + * The way reference policy and loadable policy modules handle + * file contexts makes them come out in an unpredictable order + * and therefore setfiles (or this standalone tool) need to sort + * the regular expressions in a deterministic and stable way. + */ + +#define BUF_SIZE 4096; +#define _GNU_SOURCE + +#include +#include +#include +#include + +typedef unsigned char bool_t; + +/* file_context_node + * A node used in a linked list of file contexts.c + * Each node contains the regular expression, the type and + * the context, as well as information about the regular + * expression. The regular expression data (meta, stem_len + * and str_len) can be filled in by using the fc_fill_data + * function after the regular expression has been loaded. + * next points to the next node in the linked list. + */ +typedef struct file_context_node { + char *path; + char *file_type; + char *context; + bool_t meta; + int stem_len; + int str_len; + struct file_context_node *next; +} file_context_node_t; + +void file_context_node_destroy(file_context_node_t *x) +{ + free(x->path); + free(x->file_type); + free(x->context); +} + + + +/* file_context_bucket + * A node used in a linked list of buckets that contain + * file_context_node's. + * Each node contains a pointer to a file_context_node which + * is the header of its linked list. This linked list is the + * content of this bucket. + * next points to the next bucket in the linked list. + */ +typedef struct file_context_bucket { + file_context_node_t *data; + struct file_context_bucket *next; +} file_context_bucket_t; + + + +/* fc_compare + * Compares two file contexts' regular expressions and returns: + * -1 if a is less specific than b + * 0 if a and be are equally specific + * 1 if a is more specific than b + * The comparison is based on the following statements, + * in order from most important to least important, given a and b: + * If a is a regular expression and b is not, + * -> a is less specific than b. + * If a's stem length is shorter than b's stem length, + * -> a is less specific than b. + * If a's string length is shorter than b's string length, + * -> a is less specific than b. + * If a does not have a specified type and b does not, + * -> a is less specific than b. + */ +int fc_compare(file_context_node_t *a, file_context_node_t *b) +{ + /* Check to see if either a or b have meta characters + * and the other doesn't. */ + if (a->meta && !b->meta) + return -1; + if (b->meta && !a->meta) + return 1; + + /* Check to see if either a or b have a shorter stem + * length than the other. */ + if (a->stem_len < b->stem_len) + return -1; + if (b->stem_len < a->stem_len) + return 1; + + /* Check to see if either a or b have a shorter string + * length than the other. */ + if (a->str_len < b->str_len) + return -1; + if (b->str_len < a->str_len) + return 1; + + /* Check to see if either a or b has a specified type + * and the other doesn't. */ + if (!a->file_type && b->file_type) + return -1; + if (!b->file_type && a->file_type) + return 1; + + /* If none of the above conditions were satisfied, + * then a and b are equally specific. */ + return 0; +} + + + +/* fc_merge + * Merges two sorted file context linked lists into one + * sorted one. + * Pass two lists a and b, and after the completion of fc_merge, + * the final list is contained in a, and b is empty. + */ +file_context_node_t *fc_merge(file_context_node_t *a, + file_context_node_t *b) +{ + file_context_node_t *a_current; + file_context_node_t *b_current; + file_context_node_t *temp; + file_context_node_t *jumpto; + + + + /* If a is a empty list, and b is not, + * set a as b and proceed to the end. */ + if (!a && b) + a = b; + /* If b is an empty list, leave a as it is. */ + else if (!b) { + } else { + /* Make it so the list a has the lesser + * first element always. */ + if (fc_compare(a, b) == 1) { + temp = a; + a = b; + b = temp; + } + a_current = a; + b_current = b; + + /* Merge by inserting b's nodes in between a's nodes. */ + while (a_current->next && b_current) { + jumpto = a_current->next; + + /* Insert b's nodes in between the current a node + * and the next a node.*/ + while (b_current && a_current->next && + fc_compare(a_current->next, + b_current) != -1) { + + + temp = a_current->next; + a_current->next = b_current; + b_current = b_current->next; + a_current->next->next = temp; + a_current = a_current->next; + } + + /* Skip all the inserted node from b to the + * next node in the original a. */ + a_current = jumpto; + } + + + /* if there is anything left in b to be inserted, + put it on the end */ + if (b_current) { + a_current->next = b_current; + } + } + + return a; +} + + + +/* fc_merge_sort + * Sorts file contexts from least specific to more specific. + * The bucket linked list is passed and after the completion + * of the fc_merge_sort function, there is only one bucket + * (pointed to by master) that contains a linked list + * of all the file contexts, in sorted order. + * Explanation of the algorithm: + * The algorithm implemented in fc_merge_sort is an iterative + * implementation of merge sort. + * At first, each bucket has a linked list of file contexts + * that are 1 element each. + * Each pass, each odd numbered bucket is merged into the bucket + * before it. This halves the number of buckets each pass. + * It will continue passing over the buckets (as described above) + * until there is only one bucket left, containing the list of + * file contexts, sorted. + */ +void fc_merge_sort(file_context_bucket_t *master) +{ + + + file_context_bucket_t *current; + file_context_bucket_t *temp; + + /* Loop until master is the only bucket left + * so that this will stop when master contains + * the sorted list. */ + while (master->next) { + current = master; + + /* This loop merges buckets two-by-two. */ + while (current) { + + if (current->next) { + + current->data = + fc_merge(current->data, + current->next->data); + + + + temp = current->next; + current->next = current->next->next; + + free(temp); + + } + + + current = current->next; + } + } + + +} + + + +/* fc_fill_data + * This processes a regular expression in a file context + * and sets the data held in file_context_node, namely + * meta, str_len and stem_len. + * The following changes are made to fc_node after the + * the completion of the function: + * fc_node->meta = 1 if path has a meta character, 0 if not. + * fc_node->str_len = The string length of the entire path + * fc_node->stem_len = The number of characters up until + * the first meta character. + */ +void fc_fill_data(file_context_node_t *fc_node) +{ + int c = 0; + + fc_node->meta = 0; + fc_node->stem_len = 0; + fc_node->str_len = 0; + + /* Process until the string termination character + * has been reached. + * Note: this while loop has been adapted from + * spec_hasMetaChars in matchpathcon.c from + * libselinux-1.22. */ + while (fc_node->path[c] != '\0') { + switch (fc_node->path[c]) { + case '.': + case '^': + case '$': + case '?': + case '*': + case '+': + case '|': + case '[': + case '(': + case '{': + /* If a meta character is found, + * set meta to one */ + fc_node->meta = 1; + break; + case '\\': + /* If a escape character is found, + * skip the next character. */ + c++; + default: + /* If no meta character has been found yet, + * add one to the stem length. */ + if (!fc_node->meta) + fc_node->stem_len++; + break; + } + + fc_node->str_len++; + c++; + } +} + +/* main + * This program takes in two arguments, the input filename and the + * output filename. The input file should be syntactically correct. + * Overall what is done in the main is read in the file and store each + * line of code, sort it, then output it to the output file. + */ +int main(int argc, char *argv[]) +{ + int lines; + size_t start, finish, regex_len, context_len; + size_t line_len, buf_len, i, j; + char *input_name, *output_name, *line_buf; + + file_context_node_t *temp; + file_context_node_t *head; + file_context_node_t *current; + file_context_bucket_t *master; + file_context_bucket_t *bcurrent; + + FILE *in_file, *out_file; + + + /* Check for the correct number of command line arguments. */ + if (argc != 3) { + fprintf(stderr, "Usage: %s \n",argv[0]); + return 1; + } + + input_name = argv[1]; + output_name = argv[2]; + + i = j = lines = 0; + + /* Open the input file. */ + if (!(in_file = fopen(input_name, "r"))) { + fprintf(stderr, "Error: failure opening input file for read.\n"); + return 1; + } + + /* Initialize the head of the linked list. */ + head = current = (file_context_node_t*)malloc(sizeof(file_context_node_t)); + + /* Parse the file into a file_context linked list. */ + line_buf = NULL; + + while ( getline(&line_buf, &buf_len, in_file) != -1 ){ + line_len = strlen(line_buf); + if( line_len == 0 || line_len == 1) + continue; + /* Get rid of whitespace from the front of the line. */ + for (i = 0; i < line_len; i++) { + if (!isspace(line_buf[i])) + break; + } + + + if (i >= line_len) + continue; + /* Check if the line isn't empty and isn't a comment */ + if (line_buf[i] == '#') + continue; + + /* We have a valid line - allocate a new node. */ + temp = (file_context_node_t *)malloc(sizeof(file_context_node_t)); + if (!temp) { + fprintf(stderr, "Error: failure allocating memory.\n"); + return 1; + } + temp->next = NULL; + memset(temp, 0, sizeof(file_context_node_t)); + + /* Parse out the regular expression from the line. */ + start = i; + + + while (i < line_len && (!isspace(line_buf[i]))) + i++; + finish = i; + + + regex_len = finish - start; + + if (regex_len == 0) { + file_context_node_destroy(temp); + free(temp); + + + continue; + } + + temp->path = (char*)strndup(&line_buf[start], regex_len); + if (!temp->path) { + file_context_node_destroy(temp); + free(temp); + fprintf(stderr, "Error: failure allocating memory.\n"); + return 1; + } + + /* Get rid of whitespace after the regular expression. */ + for (; i < line_len; i++) { + + if (!isspace(line_buf[i])) + break; + } + + if (i == line_len) { + file_context_node_destroy(temp); + free(temp); + continue; + } + + /* Parse out the type from the line (if it + * is there). */ + if (line_buf[i] == '-') { + temp->file_type = (char *)malloc(sizeof(char) * 3); + if (!(temp->file_type)) { + fprintf(stderr, "Error: failure allocating memory.\n"); + return 1; + } + + if( i + 2 >= line_len ) { + file_context_node_destroy(temp); + free(temp); + + continue; + } + + /* Fill the type into the array. */ + temp->file_type[0] = line_buf[i]; + temp->file_type[1] = line_buf[i + 1]; + i += 2; + temp->file_type[2] = 0; + + /* Get rid of whitespace after the type. */ + for (; i < line_len; i++) { + if (!isspace(line_buf[i])) + break; + } + + if (i == line_len) { + + file_context_node_destroy(temp); + free(temp); + continue; + } + } + + /* Parse out the context from the line. */ + start = i; + while (i < line_len && (!isspace(line_buf[i]))) + i++; + finish = i; + + context_len = finish - start; + + temp->context = (char*)strndup(&line_buf[start], context_len); + if (!temp->context) { + file_context_node_destroy(temp); + free(temp); + fprintf(stderr, "Error: failure allocating memory.\n"); + return 1; + } + + /* Set all the data about the regular + * expression. */ + fc_fill_data(temp); + + /* Link this line of code at the end of + * the linked list. */ + current->next = temp; + current = current->next; + lines++; + + + free(line_buf); + line_buf = NULL; + } + fclose(in_file); + + /* Create the bucket linked list from the earlier linked list. */ + current = head->next; + bcurrent = master = + (file_context_bucket_t *) + malloc(sizeof(file_context_bucket_t)); + + /* Go until all the nodes have been put in individual buckets. */ + while (current) { + /* Copy over the file context line into the bucket. */ + bcurrent->data = current; + current = current->next; + + /* Detatch the node in the bucket from the old list. */ + bcurrent->data->next = NULL; + + /* If there should be another bucket, put one at the end. */ + if (current) { + bcurrent->next = + (file_context_bucket_t *) + malloc(sizeof(file_context_bucket_t)); + if (!(bcurrent->next)) { + printf + ("Error: failure allocating memory.\n"); + return -1; + } + + /* Make sure the new bucket thinks it's the end of the + * list. */ + bcurrent->next->next = NULL; + + bcurrent = bcurrent->next; + } + + } + + /* Sort the bucket list. */ + fc_merge_sort(master); + + /* Open the output file. */ + if (!(out_file = fopen(argv[2], "w"))) { + printf("Error: failure opening output file for write.\n"); + return -1; + } + + /* Output the sorted file_context linked list to the output file. */ + current = master->data; + while (current) { + /* Output the path. */ + fprintf(out_file, "%s\t\t", current->path); + + /* Output the type, if there is one. */ + if (current->file_type) { + fprintf(out_file, "%s\t", current->file_type); + } + + /* Output the context. */ + fprintf(out_file, "%s\n", current->context); + + /* Remove the node. */ + temp = current; + current = current->next; + + file_context_node_destroy(temp); + free(temp); + + } + free(master); + + fclose(out_file); + + return 0; +} diff -r 7c771f0a24f3 -r dc417e6b868f tools/flask/policy/support/set_tunables --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/flask/policy/support/set_tunables Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,8 @@ +#!/bin/sh + +# this file exists because this line is +# too hard to escape correctly in a makefile + +if test -f $1; then + awk -F = '/^[[:blank:]]*[[:alpha:]]+/{ gsub(/[[:blank:]]*/,"") ; print "define(`"$1"_conf'\'',`"$2"'\'')" }' $1 +fi diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/Makefile --- a/tools/python/Makefile Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/python/Makefile Tue Jul 08 16:39:21 2008 -0400 @@ -1,13 +1,5 @@ XEN_ROOT = ../.. XEN_ROOT = ../.. include $(XEN_ROOT)/tools/Rules.mk - -XEN_SECURITY_MODULE = dummy -ifeq ($(FLASK_ENABLE),y) -XEN_SECURITY_MODULE = flask -endif -ifeq ($(ACM_SECURITY),y) -XEN_SECURITY_MODULE = acm -endif .PHONY: all all: build @@ -23,8 +15,8 @@ NLSDIR = /usr/share/locale NLSDIR = /usr/share/locale .PHONY: build buildpy -buildpy: xsm.py - CC="$(CC)" CFLAGS="$(CFLAGS)" XEN_SECURITY_MODULE="$(XEN_SECURITY_MODULE)" python setup.py build +buildpy: + CC="$(CC)" CFLAGS="$(CFLAGS)" python setup.py build build: buildpy refresh-pot refresh-po $(CATALOGS) @@ -61,18 +53,6 @@ refresh-po: $(POTFILE) %.mo: %.po $(MSGFMT) -c -o $@ $< -xsm.py: - @(set -e; \ - echo "XEN_SECURITY_MODULE = \""$(XEN_SECURITY_MODULE)"\""; \ - echo "from xsm_core import *"; \ - echo ""; \ - echo "import xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" as xsm_module"; \ - echo ""; \ - echo "xsm_init(xsm_module)"; \ - echo "from xen.util.xsm."$(XEN_SECURITY_MODULE)"."$(XEN_SECURITY_MODULE)" import *"; \ - echo "del xsm_module"; \ - echo "") >xen/util/xsm/$@ - .PHONY: install ifndef XEN_PYTHON_NATIVE_INSTALL install: LIBPATH=$(shell PYTHONPATH=xen/util python -c "import auxbin; print auxbin.libpath()") @@ -104,4 +84,4 @@ test: .PHONY: clean clean: - rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) xen/util/xsm/xsm.py xen/util/auxbin.pyc + rm -rf build *.pyc *.pyo *.o *.a *~ $(CATALOGS) xen/util/auxbin.pyc diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/xen/util/xsconstants.py --- a/tools/python/xen/util/xsconstants.py Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/python/xen/util/xsconstants.py Tue Jul 08 16:39:21 2008 -0400 @@ -20,8 +20,10 @@ XS_INST_BOOT = (1 << 0) XS_INST_BOOT = (1 << 0) XS_INST_LOAD = (1 << 1) -XS_POLICY_NONE = 0 +XS_POLICY_DUMMY = 0 XS_POLICY_ACM = (1 << 0) +XS_POLICY_FLASK = (1 << 1) +XS_POLICY_USE = 0 # Some internal variables used by the Xen-API ACM_LABEL_VM = (1 << 0) diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/xen/util/xsm/dummy/dummy.py --- a/tools/python/xen/util/xsm/dummy/dummy.py Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/python/xen/util/xsm/dummy/dummy.py Tue Jul 08 16:39:21 2008 -0400 @@ -36,7 +36,7 @@ def err(msg): raise XSMError(msg) def on(): - return 0 + return xsconstants.XS_POLICY_DUMMY def ssidref2label(ssidref): return 0 diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/xen/util/xsm/flask/flask.py --- a/tools/python/xen/util/xsm/flask/flask.py Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/python/xen/util/xsm/flask/flask.py Tue Jul 08 16:39:21 2008 -0400 @@ -12,7 +12,7 @@ def err(msg): raise XSMError(msg) def on(): - return 0 #xsconstants.XS_POLICY_FLASK + return xsconstants.XS_POLICY_FLASK def ssidref2label(ssidref): try: @@ -30,6 +30,7 @@ def parse_security_label(security_label) return security_label def calc_dom_ssidref_from_info(info): + log.debug(info) ssidref = label2ssidref(info['security_label'], "", "") return ssidref @@ -37,8 +38,9 @@ def set_security_label(policy, label): return label def ssidref2security_label(ssidref): - return ssidref2label(ssidref) + label = ssidref2label(ssidref) + return label def get_security_label(self, xspol=None): - label = self.info.get('security_label', '') + label = self.info['security_label'] return label diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/xen/util/xsm/xsm.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/python/xen/util/xsm/xsm.py Tue Jul 08 16:39:21 2008 -0400 @@ -0,0 +1,15 @@ +from xen.xend import XendOptions +from xen.util import xsconstants +from xsm_core import * +import string + +xoptions = XendOptions.instance() +xsm_module_name = xoptions.get_xsm_module_name() + +xsconstants.XS_POLICY_USE = eval("xsconstants.XS_POLICY_"+string.upper(xsm_module_name)) + +exec "import xen.util.xsm." + xsm_module_name + "." + xsm_module_name + " as xsm_module" +xsm_init(xsm_module) +exec "from xen.util.xsm." + xsm_module_name + "." + xsm_module_name + " import *" +del xsm_module + diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/xen/xend/XendConfig.py --- a/tools/python/xen/xend/XendConfig.py Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/python/xen/xend/XendConfig.py Tue Jul 08 16:39:21 2008 -0400 @@ -726,7 +726,7 @@ class XendConfig(dict): self.parse_cpuid(cfg, 'cpuid_check') import xen.util.xsm.xsm as security - if security.on() == xsconstants.XS_POLICY_ACM: + if security.on() == xsconstants.XS_POLICY_USE: from xen.util.acmpolicy import ACM_LABEL_UNLABELED if not 'security' in cfg and sxp.child_value(sxp_cfg, 'security'): cfg['security'] = sxp.child_value(sxp_cfg, 'security') diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/python/xen/xend/XendDomainInfo.py Tue Jul 08 16:39:21 2008 -0400 @@ -1981,7 +1981,7 @@ class XendDomainInfo: balloon.free(2*1024) # 2MB should be plenty ssidref = 0 - if security.on() == xsconstants.XS_POLICY_ACM: + if security.on() == xsconstants.XS_POLICY_USE: ssidref = security.calc_dom_ssidref_from_info(self.info) if security.has_authorization(ssidref) == False: raise VmError("VM is not authorized to run.") @@ -2762,10 +2762,6 @@ class XendDomainInfo: if info["maxmem_kb"] < 0: info["maxmem_kb"] = XendNode.instance() \ .physinfo_dict()['total_memory'] * 1024 - - #ssidref field not used any longer - if 'ssidref' in info: - info.pop('ssidref') # make sure state is reset for info # TODO: we should eventually get rid of old_dom_states diff -r 7c771f0a24f3 -r dc417e6b868f tools/python/xen/xend/XendOptions.py --- a/tools/python/xen/xend/XendOptions.py Wed Jun 11 11:35:35 2008 +0100 +++ b/tools/python/xen/xend/XendOptions.py Tue Jul 08 16:39:21 2008 -0400 @@ -131,6 +131,9 @@ class XendOptions: """Default script to configure a backend network interface""" vif_script = osdep.vif_script + + """Default Xen Security Module""" + xsm_module_default = 'dummy' def __init__(self): self.configure() @@ -420,6 +423,11 @@ class XendOptionsFile(XendOptions): return self.get_config_value('xen-api-server', self.xen_api_server_default) + def get_xsm_module_name(self): + """Get the Xen Security Module name. + """ + return self.get_config_string('xsm_module_name', self.xsm_module_default) + if os.uname()[0] == 'SunOS': class XendOptionsSMF(XendOptions): diff -r 7c771f0a24f3 -r dc417e6b868f xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/arch/x86/domctl.c Tue Jul 08 16:39:21 2008 -0400 @@ -67,14 +67,6 @@ long arch_do_domctl( ret = -ESRCH; if ( unlikely((d = rcu_lock_domain_by_id(domctl->domain)) == NULL) ) break; - - ret = xsm_ioport_permission(d, fp, - domctl->u.ioport_permission.allow_access); - if ( ret ) - { - rcu_unlock_domain(d); - break; - } if ( np == 0 ) ret = 0; @@ -499,6 +491,10 @@ long arch_do_domctl( if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; + ret = xsm_sendtrigger(d); + if ( ret ) + goto sendtrigger_out; + ret = -EINVAL; if ( domctl->u.sendtrigger.vcpu >= MAX_VIRT_CPUS ) goto sendtrigger_out; @@ -577,6 +573,10 @@ long arch_do_domctl( bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff; devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff; + ret = xsm_test_assign_device(domctl->u.assign_device.machine_bdf); + if ( ret ) + break; + if ( device_assigned(bus, devfn) ) { gdprintk(XENLOG_ERR, "XEN_DOMCTL_test_assign_device: " @@ -604,6 +604,11 @@ long arch_do_domctl( "XEN_DOMCTL_assign_device: get_domain_by_id() failed\n"); break; } + + ret = xsm_assign_device(d, domctl->u.assign_device.machine_bdf); + if ( ret ) + goto assign_device_out; + bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff; devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff; @@ -624,6 +629,8 @@ long arch_do_domctl( ret = assign_device(d, bus, devfn); gdprintk(XENLOG_INFO, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + assign_device_out: put_domain(d); } break; @@ -644,6 +651,11 @@ long arch_do_domctl( "XEN_DOMCTL_deassign_device: get_domain_by_id() failed\n"); break; } + + ret = xsm_assign_device(d, domctl->u.assign_device.machine_bdf); + if ( ret ) + goto deassign_device_out; + bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff; devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff; @@ -660,6 +672,8 @@ long arch_do_domctl( deassign_device(d, bus, devfn); gdprintk(XENLOG_INFO, "XEN_DOMCTL_deassign_device: bdf = %x:%x:%x\n", bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); + + deassign_device_out: put_domain(d); } break; @@ -673,10 +687,17 @@ long arch_do_domctl( if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL ) break; bind = &(domctl->u.bind_pt_irq); + + ret = xsm_bind_pt_irq(d, bind); + if ( ret ) + goto bind_out; + if ( iommu_enabled ) ret = pt_irq_create_bind_vtd(d, bind); if ( ret < 0 ) gdprintk(XENLOG_ERR, "pt_irq_create_bind failed!\n"); + + bind_out: rcu_unlock_domain(d); } break; @@ -817,11 +838,16 @@ long arch_do_domctl( if ( d == NULL ) break; + ret = xsm_pin_mem_cacheattr(d); + if ( ret ) + goto pin_out; + ret = hvm_set_mem_pinned_cacheattr( d, domctl->u.pin_mem_cacheattr.start, domctl->u.pin_mem_cacheattr.end, domctl->u.pin_mem_cacheattr.type); + pin_out: rcu_unlock_domain(d); } break; @@ -839,6 +865,10 @@ long arch_do_domctl( d = rcu_lock_domain_by_id(domctl->domain); if ( d == NULL ) break; + + ret = xsm_ext_vcpucontext(d, domctl->cmd); + if ( ret ) + goto ext_vcpucontext_out; ret = -ESRCH; if ( (evc->vcpu >= MAX_VIRT_CPUS) || diff -r 7c771f0a24f3 -r dc417e6b868f xen/arch/x86/platform_hypercall.c --- a/xen/arch/x86/platform_hypercall.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/arch/x86/platform_hypercall.c Tue Jul 08 16:39:21 2008 -0400 @@ -193,6 +193,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe break; case XENPF_firmware_info: + ret = xsm_firmware_info(); + if ( ret ) + break; + switch ( op->u.firmware_info.type ) { case XEN_FW_DISK_INFO: { @@ -281,10 +285,18 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe break; case XENPF_enter_acpi_sleep: + ret = xsm_acpi_sleep(); + if ( ret ) + break; + ret = acpi_enter_sleep(&op->u.enter_acpi_sleep); break; case XENPF_change_freq: + ret = xsm_change_freq(); + if ( ret ) + break; + ret = -ENOSYS; if ( cpufreq_controller != FREQCTL_dom0_kernel ) break; @@ -306,6 +318,10 @@ ret_t do_platform_op(XEN_GUEST_HANDLE(xe cpumask_t cpumap; XEN_GUEST_HANDLE(uint8) cpumap_bitmap; XEN_GUEST_HANDLE(uint64) idletimes; + + ret = xsm_getidletime(); + if ( ret ) + break; ret = -ENOSYS; if ( cpufreq_controller != FREQCTL_dom0_kernel ) diff -r 7c771f0a24f3 -r dc417e6b868f xen/common/domctl.c --- a/xen/common/domctl.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/common/domctl.c Tue Jul 08 16:39:21 2008 -0400 @@ -728,16 +728,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( d == NULL ) break; - ret = xsm_irq_permission(d, pirq, op->u.irq_permission.allow_access); - if ( ret ) - goto irq_permission_out; - if ( op->u.irq_permission.allow_access ) ret = irq_permit_access(d, pirq); else ret = irq_deny_access(d, pirq); - irq_permission_out: rcu_unlock_domain(d); } break; @@ -757,16 +752,11 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc if ( d == NULL ) break; - ret = xsm_iomem_permission(d, mfn, op->u.iomem_permission.allow_access); - if ( ret ) - goto iomem_permission_out; - if ( op->u.iomem_permission.allow_access ) ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1); else ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1); - iomem_permission_out: rcu_unlock_domain(d); } break; @@ -814,6 +804,12 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc goto set_target_out; } + ret = xsm_set_target(d, e); + if ( ret ) { + put_domain(e); + goto set_target_out; + } + /* Hold reference on @e until we destroy @d. */ d->target = e; diff -r 7c771f0a24f3 -r dc417e6b868f xen/common/rangeset.c --- a/xen/common/rangeset.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/common/rangeset.c Tue Jul 08 16:39:21 2008 -0400 @@ -10,6 +10,7 @@ #include #include #include +#include /* An inclusive range [s,e] and pointer to next range in ascending order. */ struct range { @@ -96,6 +97,10 @@ int rangeset_add_range( struct range *x, *y; int rc = 0; + rc = xsm_add_range(r->domain, r->name, s, e); + if ( rc ) + return rc; + ASSERT(s <= e); spin_lock(&r->lock); @@ -163,6 +168,10 @@ int rangeset_remove_range( { struct range *x, *y, *t; int rc = 0; + + rc = xsm_remove_range(r->domain, r->name, s, e); + if ( rc ) + return rc; ASSERT(s <= e); diff -r 7c771f0a24f3 -r dc417e6b868f xen/common/sysctl.c --- a/xen/common/sysctl.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/common/sysctl.c Tue Jul 08 16:39:21 2008 -0400 @@ -149,6 +149,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc char c; uint32_t i; + ret = xsm_debug_keys(); + if ( ret ) + break; + for ( i = 0; i < op->u.debug_keys.nr_keys; i++ ) { if ( copy_from_guest_offset(&c, op->u.debug_keys.keys, i, 1) ) @@ -165,6 +169,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc struct vcpu *v; nr_cpus = min_t(uint32_t, op->u.getcpuinfo.max_cpus, NR_CPUS); + + ret = xsm_getcpuinfo(); + if ( ret ) + break; for ( i = 0; i < nr_cpus; i++ ) { @@ -188,6 +196,10 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysc case XEN_SYSCTL_availheap: { + ret = xsm_availheap(); + if ( ret ) + break; + op->u.availheap.avail_bytes = avail_domheap_pages_region( op->u.availheap.node, op->u.availheap.min_bitwidth, diff -r 7c771f0a24f3 -r dc417e6b868f xen/include/xsm/xsm.h --- a/xen/include/xsm/xsm.h Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/include/xsm/xsm.h Tue Jul 08 16:39:21 2008 -0400 @@ -64,16 +64,17 @@ struct xsm_operations { int (*getvcpucontext) (struct domain *d); int (*getvcpuinfo) (struct domain *d); int (*domain_settime) (struct domain *d); + int (*set_target) (struct domain *d, struct domain *e); int (*tbufcontrol) (void); int (*readconsole) (uint32_t clear); int (*sched_id) (void); int (*setdomainmaxmem) (struct domain *d); int (*setdomainhandle) (struct domain *d); int (*setdebugging) (struct domain *d); - int (*irq_permission) (struct domain *d, uint8_t pirq, uint8_t access); - int (*iomem_permission) (struct domain *d, unsigned long mfn, - uint8_t access); int (*perfcontrol) (void); + int (*debug_keys) (void); + int (*getcpuinfo) (void); + int (*availheap) (void); int (*evtchn_unbound) (struct domain *d, struct evtchn *chn, domid_t id2); int (*evtchn_interdomain) (struct domain *d1, struct evtchn *chn1, @@ -107,13 +108,15 @@ struct xsm_operations { int (*kexec) (void); int (*schedop_shutdown) (struct domain *d1, struct domain *d2); + int (*add_range) (struct domain *d, char *name, unsigned long s, + unsigned long e); + int (*remove_range) (struct domain *d, char *name, unsigned long s, + unsigned long e); + long (*__do_xsm_op) (XEN_GUEST_HANDLE(xsm_op_t) op); - void (*complete_init) (struct domain *d); #ifdef CONFIG_X86 int (*shadow_control) (struct domain *d, uint32_t op); - int (*ioport_permission) (struct domain *d, uint32_t ioport, - uint8_t access); int (*getpageframeinfo) (struct page_info *page); int (*getmemlist) (struct domain *d); int (*hypercall_init) (struct domain *d); @@ -130,12 +133,23 @@ struct xsm_operations { int (*microcode) (void); int (*physinfo) (void); int (*platform_quirk) (uint32_t); + int (*firmware_info) (void); + int (*acpi_sleep) (void); + int (*change_freq) (void); + int (*getidletime) (void); int (*machine_memory_map) (void); int (*domain_memory_map) (struct domain *d); int (*mmu_normal_update) (struct domain *d, intpte_t fpte); int (*mmu_machphys_update) (struct domain *d, unsigned long mfn); int (*update_va_mapping) (struct domain *d, l1_pgentry_t pte); int (*add_to_physmap) (struct domain *d1, struct domain *d2); + int (*sendtrigger) (struct domain *d); + int (*test_assign_device) (uint32_t machine_bdf); + int (*assign_device) (struct domain *d, uint32_t machine_bdf); + int (*deassign_device) (struct domain *d, uint32_t machine_bdf); + int (*bind_pt_irq) (struct domain *d, struct xen_domctl_bind_pt_irq *bind); + int (*pin_mem_cacheattr) (struct domain *d); + int (*ext_vcpucontext) (struct domain *d, uint32_t cmd); #endif }; @@ -214,6 +228,11 @@ static inline int xsm_domain_settime (st return xsm_call(domain_settime(d)); } +static inline int xsm_set_target (struct domain *d, struct domain *e) +{ + return xsm_call(set_target(d, e)); +} + static inline int xsm_tbufcontrol (void) { return xsm_call(tbufcontrol()); @@ -244,21 +263,24 @@ static inline int xsm_setdebugging (stru return xsm_call(setdebugging(d)); } -static inline int xsm_irq_permission (struct domain *d, uint8_t pirq, - uint8_t access) -{ - return xsm_call(irq_permission(d, pirq, access)); -} - -static inline int xsm_iomem_permission (struct domain *d, unsigned long mfn, - uint8_t access) -{ - return xsm_call(iomem_permission(d, mfn, access)); -} - static inline int xsm_perfcontrol (void) { return xsm_call(perfcontrol()); +} + +static inline int xsm_debug_keys (void) +{ + return xsm_call(debug_keys()); +} + +static inline int xsm_availheap (void) +{ + return xsm_call(availheap()); +} + +static inline int xsm_getcpuinfo (void) +{ + return xsm_call(getcpuinfo()); } static inline int xsm_evtchn_unbound (struct domain *d1, struct evtchn *chn, @@ -386,14 +408,21 @@ static inline int xsm_schedop_shutdown ( return xsm_call(schedop_shutdown(d1, d2)); } +static inline int xsm_add_range (struct domain *d, char *name, unsigned long s, + unsigned long e) +{ + return xsm_call(add_range(d, name, s, e)); +} + +static inline int xsm_remove_range (struct domain *d, char *name, unsigned long s, + unsigned long e) +{ + return xsm_call(remove_range(d, name, s, e)); +} + static inline long __do_xsm_op (XEN_GUEST_HANDLE(xsm_op_t) op) { return xsm_call(__do_xsm_op(op)); -} - -static inline void xsm_complete_init (struct domain *d) -{ - xsm_call(complete_init(d)); } #ifdef XSM_ENABLE @@ -415,12 +444,6 @@ static inline int xsm_shadow_control (st static inline int xsm_shadow_control (struct domain *d, uint32_t op) { return xsm_call(shadow_control(d, op)); -} - -static inline int xsm_ioport_permission (struct domain *d, uint32_t ioport, - uint8_t access) -{ - return xsm_call(ioport_permission(d, ioport, access)); } static inline int xsm_getpageframeinfo (struct page_info *page) @@ -503,6 +526,26 @@ static inline int xsm_platform_quirk (ui return xsm_call(platform_quirk(quirk)); } +static inline int xsm_firmware_info (void) +{ + return xsm_call(firmware_info()); +} + +static inline int xsm_acpi_sleep (void) +{ + return xsm_call(acpi_sleep()); +} + +static inline int xsm_change_freq (void) +{ + return xsm_call(change_freq()); +} + +static inline int xsm_getidletime (void) +{ + return xsm_call(getidletime()); +} + static inline int xsm_machine_memory_map(void) { return xsm_call(machine_memory_map()); @@ -532,6 +575,42 @@ static inline int xsm_add_to_physmap(str { return xsm_call(add_to_physmap(d1, d2)); } + +static inline int xsm_sendtrigger(struct domain *d) +{ + return xsm_call(sendtrigger(d)); +} + +static inline int xsm_test_assign_device(uint32_t machine_bdf) +{ + return xsm_call(test_assign_device(machine_bdf)); +} + +static inline int xsm_assign_device(struct domain *d, uint32_t machine_bdf) +{ + return xsm_call(assign_device(d, machine_bdf)); +} + +static inline int xsm_deassign_device(struct domain *d, uint32_t machine_bdf) +{ + return xsm_call(deassign_device(d, machine_bdf)); +} + +static inline int xsm_bind_pt_irq(struct domain *d, + struct xen_domctl_bind_pt_irq *bind) +{ + return xsm_call(bind_pt_irq(d, bind)); +} + +static inline int xsm_pin_mem_cacheattr(struct domain *d) +{ + return xsm_call(pin_mem_cacheattr(d)); +} + +static inline int xsm_ext_vcpucontext(struct domain *d, uint32_t cmd) +{ + return xsm_call(ext_vcpucontext(d, cmd)); +} #endif /* CONFIG_X86 */ #endif /* __XSM_H */ diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/dummy.c --- a/xen/xsm/dummy.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/dummy.c Tue Jul 08 16:39:21 2008 -0400 @@ -84,6 +84,11 @@ static int dummy_domain_settime (struct return 0; } +static int dummy_set_target (struct domain *d, struct domain *e) +{ + return 0; +} + static int dummy_tbufcontrol (void) { return 0; @@ -114,18 +119,22 @@ static int dummy_setdebugging (struct do return 0; } -static int dummy_irq_permission (struct domain *d, uint8_t pirq, uint8_t access) +static int dummy_perfcontrol (void) { return 0; } -static int dummy_iomem_permission (struct domain *d, unsigned long mfn, - uint8_t access) +static int dummy_debug_keys (void) { return 0; } -static int dummy_perfcontrol (void) +static int dummy_getcpuinfo (void) +{ + return 0; +} + +static int dummy_availheap (void) { return 0; } @@ -254,9 +263,16 @@ static void dummy_free_security_evtchn ( return; } -static void dummy_complete_init (struct domain *d) +static int dummy_add_range (struct domain *d, char *name, unsigned long s, + unsigned long e) { - return; + return 0; +} + +static int dummy_remove_range (struct domain *d, char *name, unsigned long s, + unsigned long e) +{ + return 0; } static long dummy___do_xsm_op(XEN_GUEST_HANDLE(xsm_op_t) op) @@ -266,12 +282,6 @@ static long dummy___do_xsm_op(XEN_GUEST_ #ifdef CONFIG_X86 static int dummy_shadow_control (struct domain *d, uint32_t op) -{ - return 0; -} - -static int dummy_ioport_permission (struct domain *d, uint32_t ioport, - uint8_t access) { return 0; } @@ -356,6 +366,26 @@ static int dummy_platform_quirk (uint32_ return 0; } +static int dummy_firmware_info (void) +{ + return 0; +} + +static int dummy_acpi_sleep (void) +{ + return 0; +} + +static int dummy_change_freq (void) +{ + return 0; +} + +static int dummy_getidletime (void) +{ + return 0; +} + static int dummy_machine_memory_map (void) { return 0; @@ -382,6 +412,41 @@ static int dummy_update_va_mapping (stru } static int dummy_add_to_physmap (struct domain *d1, struct domain *d2) +{ + return 0; +} + +static int dummy_sendtrigger (struct domain *d) +{ + return 0; +} + +static int dummy_test_assign_device (uint32_t machine_bdf) +{ + return 0; +} + +static int dummy_assign_device (struct domain *d, uint32_t machine_bdf) +{ + return 0; +} + +static int dummy_deassign_device (struct domain *d, uint32_t machine_bdf) +{ + return 0; +} + +static int dummy_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) +{ + return 0; +} + +static int dummy_pin_mem_cacheattr (struct domain *d) +{ + return 0; +} + +static int dummy_ext_vcpucontext (struct domain *d, uint32_t cmd) { return 0; } @@ -415,15 +480,17 @@ void xsm_fixup_ops (struct xsm_operation set_to_dummy_if_null(ops, getvcpucontext); set_to_dummy_if_null(ops, getvcpuinfo); set_to_dummy_if_null(ops, domain_settime); + set_to_dummy_if_null(ops, set_target); set_to_dummy_if_null(ops, tbufcontrol); set_to_dummy_if_null(ops, readconsole); set_to_dummy_if_null(ops, sched_id); set_to_dummy_if_null(ops, setdomainmaxmem); set_to_dummy_if_null(ops, setdomainhandle); set_to_dummy_if_null(ops, setdebugging); - set_to_dummy_if_null(ops, irq_permission); - set_to_dummy_if_null(ops, iomem_permission); set_to_dummy_if_null(ops, perfcontrol); + set_to_dummy_if_null(ops, debug_keys); + set_to_dummy_if_null(ops, getcpuinfo); + set_to_dummy_if_null(ops, availheap); set_to_dummy_if_null(ops, evtchn_unbound); set_to_dummy_if_null(ops, evtchn_interdomain); @@ -456,12 +523,13 @@ void xsm_fixup_ops (struct xsm_operation set_to_dummy_if_null(ops, kexec); set_to_dummy_if_null(ops, schedop_shutdown); + set_to_dummy_if_null(ops, add_range); + set_to_dummy_if_null(ops, remove_range); + set_to_dummy_if_null(ops, __do_xsm_op); - set_to_dummy_if_null(ops, complete_init); #ifdef CONFIG_X86 set_to_dummy_if_null(ops, shadow_control); - set_to_dummy_if_null(ops, ioport_permission); set_to_dummy_if_null(ops, getpageframeinfo); set_to_dummy_if_null(ops, getmemlist); set_to_dummy_if_null(ops, hypercall_init); @@ -478,11 +546,22 @@ void xsm_fixup_ops (struct xsm_operation set_to_dummy_if_null(ops, microcode); set_to_dummy_if_null(ops, physinfo); set_to_dummy_if_null(ops, platform_quirk); + set_to_dummy_if_null(ops, firmware_info); + set_to_dummy_if_null(ops, acpi_sleep); + set_to_dummy_if_null(ops, change_freq); + set_to_dummy_if_null(ops, getidletime); set_to_dummy_if_null(ops, machine_memory_map); set_to_dummy_if_null(ops, domain_memory_map); set_to_dummy_if_null(ops, mmu_normal_update); set_to_dummy_if_null(ops, mmu_machphys_update); set_to_dummy_if_null(ops, update_va_mapping); set_to_dummy_if_null(ops, add_to_physmap); + set_to_dummy_if_null(ops, sendtrigger); + set_to_dummy_if_null(ops, test_assign_device); + set_to_dummy_if_null(ops, assign_device); + set_to_dummy_if_null(ops, deassign_device); + set_to_dummy_if_null(ops, bind_pt_irq); + set_to_dummy_if_null(ops, pin_mem_cacheattr); + set_to_dummy_if_null(ops, ext_vcpucontext); #endif } diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/hooks.c --- a/xen/xsm/flask/hooks.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/hooks.c Tue Jul 08 16:39:21 2008 -0400 @@ -129,8 +129,7 @@ static int flask_evtchn_unbound(struct d if ( rc ) goto out; - rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, - EVENT__CREATE|EVENT__ALLOC, NULL); + rc = avc_has_perm(dsec->sid, newsid, SECCLASS_EVENT, EVENT__CREATE, NULL); if ( rc ) goto out; @@ -210,7 +209,22 @@ static void flask_evtchn_close_post(stru static int flask_evtchn_send(struct domain *d, struct evtchn *chn) { - return domain_has_evtchn(d, chn, EVENT__SEND); + int rc; + + switch ( chn->state ) + { + case ECS_INTERDOMAIN: + rc = domain_has_evtchn(d, chn, EVENT__SEND); + break; + case ECS_IPI: + case ECS_UNBOUND: + rc = 0; + break; + default: + rc = -EPERM; + } + + return rc; } static int flask_evtchn_status(struct domain *d, struct evtchn *chn) @@ -506,22 +520,22 @@ static int flask_domain_create(struct do dsec1 = current->domain->ssid; - if ( dsec1->create_sid == SECSID_NULL ) - dsec1->create_sid = ssidref; + if ( dsec1->create_sid == SECSID_NULL ) + dsec1->create_sid = ssidref; - rc = avc_has_perm(dsec1->sid, dsec1->create_sid, SECCLASS_DOMAIN, - DOMAIN__CREATE, NULL); - if ( rc ) + rc = avc_has_perm(dsec1->sid, dsec1->create_sid, SECCLASS_DOMAIN, + DOMAIN__CREATE, NULL); + if ( rc ) { - dsec1->create_sid = SECSID_NULL; - return rc; + dsec1->create_sid = SECSID_NULL; + return rc; } dsec2 = d->ssid; dsec2->sid = dsec1->create_sid; - dsec1->create_sid = SECSID_NULL; - dsec2->create_sid = SECSID_NULL; + dsec1->create_sid = SECSID_NULL; + dsec2->create_sid = SECSID_NULL; return rc; } @@ -592,6 +606,11 @@ static int flask_domain_settime(struct d return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__SETTIME); } +static int flask_set_target(struct domain *d, struct domain *e) +{ + return domain_has_perm(d, e, SECCLASS_DOMAIN, DOMAIN__SET_TARGET); +} + static int flask_tbufcontrol(void) { return domain_has_xen(current->domain, SECCLASS_XEN); @@ -630,6 +649,21 @@ static int flask_setdebugging(struct dom DOMAIN__SETDEBUGGING); } +static int flask_debug_keys(void) +{ + return domain_has_xen(current->domain, XEN__DEBUG); +} + +static int flask_getcpuinfo(void) +{ + return domain_has_xen(current->domain, XEN__GETCPUINFO); +} + +static int flask_availheap(void) +{ + return domain_has_xen(current->domain, XEN__HEAP); +} + static inline u32 resource_to_perm(uint8_t access) { if ( access ) @@ -638,7 +672,7 @@ static inline u32 resource_to_perm(uint8 return RESOURCE__REMOVE; } -static int flask_irq_permission(struct domain *d, uint8_t pirq, uint8_t access) +static int irq_has_perm(struct domain *d, uint8_t pirq, uint8_t access) { u32 perm; u32 rsid; @@ -665,16 +699,17 @@ static int flask_irq_permission(struct d return rc; rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, NULL); - if ( rc ) return rc; - return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, + if ( access ) + return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, NULL); + else + return rc; } -static int flask_iomem_permission(struct domain *d, unsigned long mfn, - uint8_t access) +static int iomem_has_perm(struct domain *d, unsigned long mfn, uint8_t access) { u32 perm; u32 rsid; @@ -684,7 +719,6 @@ static int flask_iomem_permission(struct rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, resource_to_perm(access)); - if ( rc ) return rc; @@ -701,29 +735,19 @@ static int flask_iomem_permission(struct return rc; rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, perm, NULL); - if ( rc ) return rc; - return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, + if ( access ) + return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, NULL); + else + return rc; } static int flask_perfcontrol(void) { return domain_has_xen(current->domain, XEN__PERFCONTROL); -} - -void flask_complete_init(struct domain *d) -{ - struct domain_security_struct *dsec; - - /* Set the security state for the Dom0 domain. */ - dsec = d->ssid; - dsec->sid = SECINITSID_DOM0; - dsec->create_sid = SECINITSID_UNLABELED; - - printk("Flask: Completed initialization.\n"); } #ifdef CONFIG_X86 @@ -755,8 +779,7 @@ static int flask_shadow_control(struct d return domain_has_perm(current->domain, d, SECCLASS_SHADOW, perm); } -static int flask_ioport_permission(struct domain *d, uint32_t ioport, - uint8_t access) +static int ioport_has_perm(struct domain *d, uint32_t ioport, uint8_t access) { u32 perm; u32 rsid; @@ -786,8 +809,11 @@ static int flask_ioport_permission(struc if ( rc ) return rc; - return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, + if ( access ) + return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, NULL); + else + return rc; } static int flask_getpageframeinfo(struct page_info *page) @@ -965,6 +991,26 @@ static int flask_platform_quirk(uint32_t XEN__QUIRK, NULL); } +static int flask_firmware_info(void) +{ + return domain_has_xen(current->domain, XEN__FIRMWARE); +} + +static int flask_acpi_sleep(void) +{ + return domain_has_xen(current->domain, XEN__SLEEP); +} + +static int flask_change_freq(void) +{ + return domain_has_xen(current->domain, XEN__FREQUENCY); +} + +static int flask_getidletime(void) +{ + return domain_has_xen(current->domain, XEN__GETIDLE); +} + static int flask_machine_memory_map(void) { struct domain_security_struct *dsec; @@ -1040,7 +1086,162 @@ static int flask_add_to_physmap(struct d { return domain_has_perm(d1, d2, SECCLASS_MMU, MMU__PHYSMAP); } + +static int flask_sendtrigger(struct domain *d) +{ + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, DOMAIN__TRIGGER); +} + +static int flask_test_assign_device(uint32_t machine_bdf) +{ + u32 rsid; + int rc = -EPERM; + struct domain_security_struct *ssec = current->domain->ssid; + + rc = security_device_sid(machine_bdf, &rsid); + if ( rc ) + return rc; + + return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, NULL); +} + +static int flask_assign_device(struct domain *d, uint32_t machine_bdf) +{ + u32 rsid; + int rc = -EPERM; + struct domain_security_struct *ssec, *tsec; + + rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + if ( rc ) + return rc; + + rc = security_device_sid(machine_bdf, &rsid); + if ( rc ) + return rc; + + ssec = current->domain->ssid; + rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, NULL); + if ( rc ) + return rc; + + tsec = d->ssid; + return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, NULL); +} + +static int flask_deassign_device(struct domain *d, uint32_t machine_bdf) +{ + u32 rsid; + int rc = -EPERM; + struct domain_security_struct *ssec = current->domain->ssid; + + rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__REMOVE); + if ( rc ) + return rc; + + rc = security_device_sid(machine_bdf, &rsid); + if ( rc ) + return rc; + + return rc = avc_has_perm(ssec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, NULL); +} + +static int flask_bind_pt_irq (struct domain *d, struct xen_domctl_bind_pt_irq *bind) +{ + u32 rsid; + int rc = -EPERM; + struct domain_security_struct *ssec, *tsec; + + rc = domain_has_perm(current->domain, d, SECCLASS_RESOURCE, RESOURCE__ADD); + if ( rc ) + return rc; + + rc = security_pirq_sid(bind->machine_irq, &rsid); + if ( rc ) + return rc; + + ssec = current->domain->ssid; + rc = avc_has_perm(ssec->sid, rsid, SECCLASS_HVM, HVM__BIND_IRQ, NULL); + if ( rc ) + return rc; + + tsec = d->ssid; + return avc_has_perm(tsec->sid, rsid, SECCLASS_RESOURCE, RESOURCE__USE, NULL); +} + +static int flask_pin_mem_cacheattr (struct domain *d) +{ + return domain_has_perm(current->domain, d, SECCLASS_HVM, HVM__CACHEATTR); +} + +static int flask_ext_vcpucontext (struct domain *d, uint32_t cmd) +{ + u32 perm; + + switch ( cmd ) + { + case XEN_DOMCTL_set_ext_vcpucontext: + perm = DOMAIN__SETEXTVCPUCONTEXT; + break; + case XEN_DOMCTL_get_ext_vcpucontext: + perm = DOMAIN__GETEXTVCPUCONTEXT; + break; + default: + return -EPERM; + } + + return domain_has_perm(current->domain, d, SECCLASS_DOMAIN, perm); +} #endif + +static int io_has_perm(struct domain *d, char *name, unsigned long s, + unsigned long e, u32 access) +{ + int rc = -EPERM; + + if ( strcmp(name, "I/O Memory") == 0 ) + { + rc = iomem_has_perm(d, s, access); + if ( rc ) + return rc; + + if ( s != e ) + rc = iomem_has_perm(d, s, access); + } + else if ( strcmp(name, "Interrupts") == 0 ) + { + rc = irq_has_perm(d, s, access); + if ( rc ) + return rc; + + if ( s != e ) + rc = irq_has_perm(d, e, access); + } +#ifdef CONFIG_X86 + else if ( strcmp(name, "I/O Ports") == 0 ) + { + rc = ioport_has_perm(d, s, access); + if ( rc ) + return rc; + + if ( s != e ) + rc = ioport_has_perm(d, e, access); + } +#endif + + return rc; +} + +static int flask_add_range(struct domain *d, char *name, unsigned long s, + unsigned long e) +{ + return io_has_perm(d, name, s, e, 1); +} + +static int flask_remove_range(struct domain *d, char *name, unsigned long s, + unsigned long e) +{ + return io_has_perm(d, name, s, e, 0); +} long do_flask_op(XEN_GUEST_HANDLE(xsm_op_t) u_flask_op); @@ -1059,15 +1260,17 @@ static struct xsm_operations flask_ops = .getvcpucontext = flask_getvcpucontext, .getvcpuinfo = flask_getvcpuinfo, .domain_settime = flask_domain_settime, + .set_target = flask_set_target, .tbufcontrol = flask_tbufcontrol, .readconsole = flask_readconsole, .sched_id = flask_sched_id, .setdomainmaxmem = flask_setdomainmaxmem, .setdomainhandle = flask_setdomainhandle, .setdebugging = flask_setdebugging, - .irq_permission = flask_irq_permission, - .iomem_permission = flask_iomem_permission, .perfcontrol = flask_perfcontrol, + .debug_keys = flask_debug_keys, + .getcpuinfo = flask_getcpuinfo, + .availheap = flask_availheap, .evtchn_unbound = flask_evtchn_unbound, .evtchn_interdomain = flask_evtchn_interdomain, @@ -1100,12 +1303,13 @@ static struct xsm_operations flask_ops = .kexec = flask_kexec, .schedop_shutdown = flask_schedop_shutdown, + .add_range = flask_add_range, + .remove_range = flask_remove_range, + .__do_xsm_op = do_flask_op, - .complete_init = flask_complete_init, #ifdef CONFIG_X86 .shadow_control = flask_shadow_control, - .ioport_permission = flask_ioport_permission, .getpageframeinfo = flask_getpageframeinfo, .getmemlist = flask_getmemlist, .hypercall_init = flask_hypercall_init, @@ -1122,12 +1326,23 @@ static struct xsm_operations flask_ops = .microcode = flask_microcode, .physinfo = flask_physinfo, .platform_quirk = flask_platform_quirk, + .firmware_info = flask_firmware_info, + .acpi_sleep = flask_acpi_sleep, + .change_freq = flask_change_freq, + .getidletime = flask_getidletime, .machine_memory_map = flask_machine_memory_map, .domain_memory_map = flask_domain_memory_map, .mmu_normal_update = flask_mmu_normal_update, .mmu_machphys_update = flask_mmu_machphys_update, .update_va_mapping = flask_update_va_mapping, .add_to_physmap = flask_add_to_physmap, + .sendtrigger = flask_sendtrigger, + .test_assign_device = flask_test_assign_device, + .assign_device = flask_assign_device, + .deassign_device = flask_deassign_device, + .bind_pt_irq = flask_bind_pt_irq, + .pin_mem_cacheattr = flask_pin_mem_cacheattr, + .ext_vcpucontext = flask_ext_vcpucontext, #endif }; diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/include/av_perm_to_string.h --- a/xen/xsm/flask/include/av_perm_to_string.h Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/include/av_perm_to_string.h Tue Jul 08 16:39:21 2008 -0400 @@ -17,11 +17,19 @@ S_(SECCLASS_XEN, XEN__PRIVPROFILE, "privprofile") S_(SECCLASS_XEN, XEN__NONPRIVPROFILE, "nonprivprofile") S_(SECCLASS_XEN, XEN__KEXEC, "kexec") + S_(SECCLASS_XEN, XEN__FIRMWARE, "firmware") + S_(SECCLASS_XEN, XEN__SLEEP, "sleep") + S_(SECCLASS_XEN, XEN__FREQUENCY, "frequency") + S_(SECCLASS_XEN, XEN__GETIDLE, "getidle") + S_(SECCLASS_XEN, XEN__DEBUG, "debug") + S_(SECCLASS_XEN, XEN__GETCPUINFO, "getcpuinfo") + S_(SECCLASS_XEN, XEN__HEAP, "heap") S_(SECCLASS_DOMAIN, DOMAIN__SETVCPUCONTEXT, "setvcpucontext") S_(SECCLASS_DOMAIN, DOMAIN__PAUSE, "pause") S_(SECCLASS_DOMAIN, DOMAIN__UNPAUSE, "unpause") S_(SECCLASS_DOMAIN, DOMAIN__RESUME, "resume") S_(SECCLASS_DOMAIN, DOMAIN__CREATE, "create") + S_(SECCLASS_DOMAIN, DOMAIN__TRANSITION, "transition") S_(SECCLASS_DOMAIN, DOMAIN__MAX_VCPUS, "max_vcpus") S_(SECCLASS_DOMAIN, DOMAIN__DESTROY, "destroy") S_(SECCLASS_DOMAIN, DOMAIN__SETVCPUAFFINITY, "setvcpuaffinity") @@ -34,11 +42,14 @@ S_(SECCLASS_DOMAIN, DOMAIN__SETDOMAINHANDLE, "setdomainhandle") S_(SECCLASS_DOMAIN, DOMAIN__SETDEBUGGING, "setdebugging") S_(SECCLASS_DOMAIN, DOMAIN__HYPERCALL, "hypercall") - S_(SECCLASS_DOMAIN, DOMAIN__TRANSITION, "transition") S_(SECCLASS_DOMAIN, DOMAIN__SETTIME, "settime") + S_(SECCLASS_DOMAIN, DOMAIN__SET_TARGET, "set_target") S_(SECCLASS_DOMAIN, DOMAIN__SHUTDOWN, "shutdown") S_(SECCLASS_DOMAIN, DOMAIN__SETADDRSIZE, "setaddrsize") S_(SECCLASS_DOMAIN, DOMAIN__GETADDRSIZE, "getaddrsize") + S_(SECCLASS_DOMAIN, DOMAIN__TRIGGER, "trigger") + S_(SECCLASS_DOMAIN, DOMAIN__GETEXTVCPUCONTEXT, "getextvcpucontext") + S_(SECCLASS_DOMAIN, DOMAIN__SETEXTVCPUCONTEXT, "setextvcpucontext") S_(SECCLASS_HVM, HVM__SETHVMC, "sethvmc") S_(SECCLASS_HVM, HVM__GETHVMC, "gethvmc") S_(SECCLASS_HVM, HVM__SETPARAM, "setparam") @@ -46,14 +57,13 @@ S_(SECCLASS_HVM, HVM__PCILEVEL, "pcilevel") S_(SECCLASS_HVM, HVM__IRQLEVEL, "irqlevel") S_(SECCLASS_HVM, HVM__PCIROUTE, "pciroute") + S_(SECCLASS_HVM, HVM__BIND_IRQ, "bind_irq") + S_(SECCLASS_HVM, HVM__CACHEATTR, "cacheattr") S_(SECCLASS_EVENT, EVENT__BIND, "bind") - S_(SECCLASS_EVENT, EVENT__CLOSE, "close") S_(SECCLASS_EVENT, EVENT__SEND, "send") S_(SECCLASS_EVENT, EVENT__STATUS, "status") - S_(SECCLASS_EVENT, EVENT__UNMASK, "unmask") S_(SECCLASS_EVENT, EVENT__NOTIFY, "notify") S_(SECCLASS_EVENT, EVENT__CREATE, "create") - S_(SECCLASS_EVENT, EVENT__ALLOC, "alloc") S_(SECCLASS_EVENT, EVENT__VECTOR, "vector") S_(SECCLASS_EVENT, EVENT__RESET, "reset") S_(SECCLASS_GRANT, GRANT__MAP_READ, "map_read") @@ -87,6 +97,9 @@ S_(SECCLASS_RESOURCE, RESOURCE__REMOVE_IOPORT, "remove_ioport") S_(SECCLASS_RESOURCE, RESOURCE__ADD_IOMEM, "add_iomem") S_(SECCLASS_RESOURCE, RESOURCE__REMOVE_IOMEM, "remove_iomem") + S_(SECCLASS_RESOURCE, RESOURCE__STAT_DEVICE, "stat_device") + S_(SECCLASS_RESOURCE, RESOURCE__ADD_DEVICE, "add_device") + S_(SECCLASS_RESOURCE, RESOURCE__REMOVE_DEVICE, "remove_device") S_(SECCLASS_SECURITY, SECURITY__COMPUTE_AV, "compute_av") S_(SECCLASS_SECURITY, SECURITY__COMPUTE_CREATE, "compute_create") S_(SECCLASS_SECURITY, SECURITY__COMPUTE_MEMBER, "compute_member") diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/include/av_permissions.h --- a/xen/xsm/flask/include/av_permissions.h Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/include/av_permissions.h Tue Jul 08 16:39:21 2008 -0400 @@ -17,29 +17,40 @@ #define XEN__PRIVPROFILE 0x00008000UL #define XEN__NONPRIVPROFILE 0x00010000UL #define XEN__KEXEC 0x00020000UL +#define XEN__FIRMWARE 0x00040000UL +#define XEN__SLEEP 0x00080000UL +#define XEN__FREQUENCY 0x00100000UL +#define XEN__GETIDLE 0x00200000UL +#define XEN__DEBUG 0x00400000UL +#define XEN__GETCPUINFO 0x00800000UL +#define XEN__HEAP 0x01000000UL #define DOMAIN__SETVCPUCONTEXT 0x00000001UL #define DOMAIN__PAUSE 0x00000002UL #define DOMAIN__UNPAUSE 0x00000004UL #define DOMAIN__RESUME 0x00000008UL #define DOMAIN__CREATE 0x00000010UL -#define DOMAIN__MAX_VCPUS 0x00000020UL -#define DOMAIN__DESTROY 0x00000040UL -#define DOMAIN__SETVCPUAFFINITY 0x00000080UL -#define DOMAIN__GETVCPUAFFINITY 0x00000100UL -#define DOMAIN__SCHEDULER 0x00000200UL -#define DOMAIN__GETDOMAININFO 0x00000400UL -#define DOMAIN__GETVCPUINFO 0x00000800UL -#define DOMAIN__GETVCPUCONTEXT 0x00001000UL -#define DOMAIN__SETDOMAINMAXMEM 0x00002000UL -#define DOMAIN__SETDOMAINHANDLE 0x00004000UL -#define DOMAIN__SETDEBUGGING 0x00008000UL -#define DOMAIN__HYPERCALL 0x00010000UL -#define DOMAIN__TRANSITION 0x00020000UL +#define DOMAIN__TRANSITION 0x00000020UL +#define DOMAIN__MAX_VCPUS 0x00000040UL +#define DOMAIN__DESTROY 0x00000080UL +#define DOMAIN__SETVCPUAFFINITY 0x00000100UL +#define DOMAIN__GETVCPUAFFINITY 0x00000200UL +#define DOMAIN__SCHEDULER 0x00000400UL +#define DOMAIN__GETDOMAININFO 0x00000800UL +#define DOMAIN__GETVCPUINFO 0x00001000UL +#define DOMAIN__GETVCPUCONTEXT 0x00002000UL +#define DOMAIN__SETDOMAINMAXMEM 0x00004000UL +#define DOMAIN__SETDOMAINHANDLE 0x00008000UL +#define DOMAIN__SETDEBUGGING 0x00010000UL +#define DOMAIN__HYPERCALL 0x00020000UL #define DOMAIN__SETTIME 0x00040000UL -#define DOMAIN__SHUTDOWN 0x00080000UL -#define DOMAIN__SETADDRSIZE 0x00100000UL -#define DOMAIN__GETADDRSIZE 0x00200000UL +#define DOMAIN__SET_TARGET 0x00080000UL +#define DOMAIN__SHUTDOWN 0x00100000UL +#define DOMAIN__SETADDRSIZE 0x00200000UL +#define DOMAIN__GETADDRSIZE 0x00400000UL +#define DOMAIN__TRIGGER 0x00800000UL +#define DOMAIN__GETEXTVCPUCONTEXT 0x01000000UL +#define DOMAIN__SETEXTVCPUCONTEXT 0x02000000UL #define HVM__SETHVMC 0x00000001UL #define HVM__GETHVMC 0x00000002UL @@ -48,17 +59,16 @@ #define HVM__PCILEVEL 0x00000010UL #define HVM__IRQLEVEL 0x00000020UL #define HVM__PCIROUTE 0x00000040UL +#define HVM__BIND_IRQ 0x00000080UL +#define HVM__CACHEATTR 0x00000100UL #define EVENT__BIND 0x00000001UL -#define EVENT__CLOSE 0x00000002UL -#define EVENT__SEND 0x00000004UL -#define EVENT__STATUS 0x00000008UL -#define EVENT__UNMASK 0x00000010UL -#define EVENT__NOTIFY 0x00000020UL -#define EVENT__CREATE 0x00000040UL -#define EVENT__ALLOC 0x00000080UL -#define EVENT__VECTOR 0x00000100UL -#define EVENT__RESET 0x00000200UL +#define EVENT__SEND 0x00000002UL +#define EVENT__STATUS 0x00000004UL +#define EVENT__NOTIFY 0x00000008UL +#define EVENT__CREATE 0x00000010UL +#define EVENT__VECTOR 0x00000020UL +#define EVENT__RESET 0x00000040UL #define GRANT__MAP_READ 0x00000001UL #define GRANT__MAP_WRITE 0x00000002UL @@ -94,6 +104,9 @@ #define RESOURCE__REMOVE_IOPORT 0x00000040UL #define RESOURCE__ADD_IOMEM 0x00000080UL #define RESOURCE__REMOVE_IOMEM 0x00000100UL +#define RESOURCE__STAT_DEVICE 0x00000200UL +#define RESOURCE__ADD_DEVICE 0x00000400UL +#define RESOURCE__REMOVE_DEVICE 0x00000800UL #define SECURITY__COMPUTE_AV 0x00000001UL #define SECURITY__COMPUTE_CREATE 0x00000002UL diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/include/flask.h --- a/xen/xsm/flask/include/flask.h Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/include/flask.h Tue Jul 08 16:39:21 2008 -0400 @@ -1,6 +1,6 @@ /* This file is automatically generated. Do not edit. */ -#ifndef _FLASK_FLASK_H_ -#define _FLASK_FLASK_H_ +#ifndef _SELINUX_FLASK_H_ +#define _SELINUX_FLASK_H_ /* * Security object class definitions @@ -27,10 +27,9 @@ #define SECINITSID_SECURITY 7 #define SECINITSID_IOPORT 8 #define SECINITSID_IOMEM 9 -#define SECINITSID_VCPU 10 -#define SECINITSID_VIRQ 11 -#define SECINITSID_PIRQ 12 +#define SECINITSID_PIRQ 10 +#define SECINITSID_DEVICE 11 -#define SECINITSID_NUM 12 +#define SECINITSID_NUM 11 #endif diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/include/initial_sid_to_string.h --- a/xen/xsm/flask/include/initial_sid_to_string.h Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/include/initial_sid_to_string.h Tue Jul 08 16:39:21 2008 -0400 @@ -11,8 +11,7 @@ static char *initial_sid_to_string[] = "security", "ioport", "iomem", - "vcpu", - "virq", "pirq", + "device", }; diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/include/security.h --- a/xen/xsm/flask/include/security.h Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/include/security.h Tue Jul 08 16:39:21 2008 -0400 @@ -69,13 +69,11 @@ int security_get_user_sids(u32 callsid, int security_pirq_sid(int pirq, u32 *out_sid); -int security_virq_sid(int virq, u32 *out_sid); - -int security_vcpu_sid(int vcpu, u32 *out_sid); - int security_iomem_sid(unsigned long, u32 *out_sid); int security_ioport_sid(u32 ioport, u32 *out_sid); + +int security_device_sid(u32 device, u32 *out_sid); int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, u16 tclass); diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/ss/policydb.h --- a/xen/xsm/flask/ss/policydb.h Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/ss/policydb.h Tue Jul 08 16:39:21 2008 -0400 @@ -133,10 +133,9 @@ struct ocontext { union { char *name; /* name of initial SID, fs, netif, fstype, path */ int pirq; - int virq; - int vcpu; u32 ioport; unsigned long iomem; + u32 device; } u; struct context context[2]; /* security context(s) */ u32 sid[2]; /* SID(s) */ @@ -157,11 +156,11 @@ struct ocontext { /* object context array indices */ #define OCON_ISID 0 /* initial SIDs */ #define OCON_PIRQ 1 /* physical irqs */ -#define OCON_VIRQ 2 /* virtual irqs */ -#define OCON_VCPU 3 /* virtual cpus */ -#define OCON_IOPORT 4 /* io ports */ -#define OCON_IOMEM 5 /* io memory */ -#define OCON_DUMMY 6 +#define OCON_IOPORT 2 /* io ports */ +#define OCON_IOMEM 3 /* io memory */ +#define OCON_DEVICE 4 /* pci devices */ +#define OCON_DUMMY1 5 /* reserved */ +#define OCON_DUMMY2 6 /* reserved */ #define OCON_NUM 7 /* The policy database */ diff -r 7c771f0a24f3 -r dc417e6b868f xen/xsm/flask/ss/services.c --- a/xen/xsm/flask/ss/services.c Wed Jun 11 11:35:35 2008 +0100 +++ b/xen/xsm/flask/ss/services.c Tue Jul 08 16:39:21 2008 -0400 @@ -1418,6 +1418,46 @@ out: return rc; } +/** + * security_ioport_sid - Obtain the SID for an ioport. + * @ioport: ioport + * @out_sid: security identifier + */ +int security_device_sid(u32 device, u32 *out_sid) +{ + struct ocontext *c; + int rc = 0; + + POLICY_RDLOCK; + + c = policydb.ocontexts[OCON_DEVICE]; + while ( c ) + { + if ( c->u.device == device ) + break; + c = c->next; + } + + if ( c ) + { + if ( !c->sid[0] ) + { + rc = sidtab_context_to_sid(&sidtab, &c->context[0], &c->sid[0]); + if ( rc ) + goto out; + } + *out_sid = c->sid[0]; + } + else + { + *out_sid = SECINITSID_DEVICE; + } + +out: + POLICY_RDUNLOCK; + return rc; +} + #define SIDS_NEL 25 /**