selinux-refpolicy/Rules.modular
Nicolas Iooss 4bd455bf90
Make "validate" target verify file contexts
When I synchronized my personal policy with the git master branch, "git
rebase" merged the file contexts I have defined for some systemd
components with the ones which have recently been merged. This resulted
in duplicated file contexts in systemd.fc, which made the policy unable
to be loaded.

This issue has not been detected by "make validate" because this command
only verifies policy linking, not the correctness of the file contexts.
Moreover this behavior of "make validate" only happens when building a
modular policy. Indeed Rules.monolithic calls setfiles in order to
validate the file contexts:

    validate: $(fc) $(polver)
        @echo "Validating $(NAME) file_contexts."
        $(verbose) $(SETFILES) -q -c $(polver) $(fc)
        @echo "Success."

Invoke setfiles in Rules.modular too in order to catch issues in file
contexts with "make validate". With the issue I experienced, I would
have got the following message:

    Validating policy file contexts.
    /sbin/setfiles -q -c tmp/policy.bin tmp/all_mods.fc
    tmp/all_mods.fc: Multiple same specifications for /run/systemd/machines(/.*)?.
    tmp/all_mods.fc: Invalid argument
    make: *** [Rules.modular:210: validate] Error 1

While at it, simplify .SECONDARY definition with a newly-introduced
$(all_mod_fc) variable.
2017-02-27 22:02:52 +01:00

225 lines
7.8 KiB
Plaintext

########################################
#
# Rules and Targets for building modular policies
#
all_modules := $(base_mods) $(mod_mods) $(off_mods)
all_interfaces := $(all_modules:.te=.if)
all_mod_fc := $(addprefix $(tmpdir)/,$(notdir $(all_modules:.te=.mod.fc)))
base_pkg := $(builddir)base.pp
base_fc := $(builddir)base.fc
base_conf := $(builddir)base.conf
base_mod := $(tmpdir)/base.mod
users_extra := $(tmpdir)/users_extra
base_sections := $(tmpdir)/pre_te_files.conf $(tmpdir)/all_attrs_types.conf $(tmpdir)/global_bools.conf $(tmpdir)/only_te_rules.conf $(tmpdir)/all_post.conf
base_pre_te_files := $(secclass) $(isids) $(avs) $(ctx_defaults) $(m4support) $(poldir)/mls $(poldir)/mcs $(policycaps)
base_te_files := $(base_mods)
base_post_te_files := $(user_files) $(poldir)/constraints
base_fc_files := $(base_mods:.te=.fc)
mod_pkgs := $(addprefix $(builddir),$(notdir $(mod_mods:.te=.pp)))
# policy packages to install
instpkg := $(addprefix $(modpkgdir)/,$(notdir $(base_pkg)) $(mod_pkgs))
# search layer dirs for source files
vpath %.te $(all_layers)
vpath %.if $(all_layers)
vpath %.fc $(all_layers)
.SECONDARY: $(all_mod_fc:.mod.fc=.mod) $(all_mod_fc)
########################################
#
# default action: create all module packages
#
default: policy
all policy: base modules
base: $(base_pkg)
modules: $(mod_pkgs)
install: $(instpkg) $(appfiles)
########################################
#
# Load all configured modules
#
load: $(instpkg) $(appfiles)
# make sure two directories exist since they are not
# created by semanage
@echo "Loading configured modules."
@$(INSTALL) -d -m 0755 $(policypath) $(dir $(fcpath))
$(verbose) $(SEMODULE) -s $(NAME) -i $(modpkgdir)/$(notdir $(base_pkg)) $(foreach mod,$(mod_pkgs),-i $(modpkgdir)/$(mod))
########################################
#
# Install policy packages
#
$(modpkgdir)/%.pp: $(builddir)%.pp
@echo "Installing $(NAME) $(@F) policy package."
@$(INSTALL) -d -m 0755 $(@D)
$(verbose) $(INSTALL) -m 0644 $^ $(modpkgdir)
########################################
#
# Build module packages
#
$(tmpdir)/%.mod: $(m4support) $(tmpdir)/generated_definitions.conf $(tmpdir)/all_interfaces.conf %.te $(m4terminate)
@echo "Compiling $(NAME) $(@F) module"
@test -d $(tmpdir) || mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) -s $^ > $(@:.mod=.tmp)
$(verbose) $(CHECKMODULE) -m $(@:.mod=.tmp) -o $@
$(tmpdir)/%.mod.fc: $(m4support) %.fc
@test -d $(tmpdir) || mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) $(m4support) $^ > $@
$(builddir)%.pp: $(tmpdir)/%.mod $(tmpdir)/%.mod.fc
@echo "Creating $(NAME) $(@F) policy package"
@test -d $(builddir) || mkdir -p $(builddir)
$(verbose) $(SEMOD_PKG) -o $@ -m $< -f $<.fc
$(tmpdir)/all_mods.fc: $(all_mod_fc)
$(verbose) cat $^ > $@
########################################
#
# Create a base module package
#
$(base_pkg): $(base_mod) $(base_fc) $(users_extra) $(tmpdir)/seusers
@echo "Creating $(NAME) base module package"
@test -d $(builddir) || mkdir -p $(builddir)
$(verbose) $(SEMOD_PKG) -o $@ -m $(base_mod) -f $(base_fc) -u $(users_extra) -s $(tmpdir)/seusers
$(base_mod): $(base_conf)
@echo "Compiling $(NAME) base module"
$(verbose) $(CHECKMODULE) -U $(UNK_PERMS) $^ -o $@
$(tmpdir)/seusers: $(seusers)
@mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) $(m4support) $^ | $(GREP) '^[a-z_]' > $@
$(users_extra): $(m4support) $(user_files)
@test -d $(tmpdir) || mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) -D users_extra $^ | \
$(SED) -r -n -e 's/^[[:blank:]]*//g' -e '/^user/p' > $@
########################################
#
# Construct a base.conf
#
$(base_conf): $(base_sections)
@echo "Creating $(NAME) base module $(@F)"
@test -d $(@D) || mkdir -p $(@D)
$(verbose) cat $^ > $@
$(tmpdir)/pre_te_files.conf: M4PARAM += -D self_contained_policy
$(tmpdir)/pre_te_files.conf: $(base_pre_te_files)
@test -d $(tmpdir) || mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) $^ > $@
$(tmpdir)/generated_definitions.conf:
@test -d $(tmpdir) || mkdir -p $(tmpdir)
# define all available object classes
$(verbose) $(genperm) $(avs) $(secclass) > $@
$(verbose) $(call create-base-per-role-tmpl,$(patsubst %.te,%,$(base_mods)),$@)
$(verbose) test -f $(booleans) && $(setbools) $(booleans) >> $@ || true
$(tmpdir)/global_bools.conf: M4PARAM += -D self_contained_policy
$(tmpdir)/global_bools.conf: $(m4support) $(tmpdir)/generated_definitions.conf $(globalbool) $(globaltun)
$(verbose) $(M4) $(M4PARAM) $^ > $@
$(tmpdir)/all_interfaces.conf: $(m4support) $(all_interfaces) $(m4iferror)
@test -d $(tmpdir) || mkdir -p $(tmpdir)
@echo "divert(-1)" > $@
$(verbose) $(M4) $^ >> $(tmpdir)/$(@F).tmp
$(verbose) $(SED) -e s/dollarsstar/\$$\*/g $(tmpdir)/$(@F).tmp >> $@
@echo "divert" >> $@
$(tmpdir)/all_te_files.conf: M4PARAM += -D self_contained_policy
$(tmpdir)/all_te_files.conf: $(m4support) $(tmpdir)/generated_definitions.conf $(tmpdir)/all_interfaces.conf $(base_te_files) $(m4terminate)
ifeq "$(strip $(base_te_files))" ""
$(error No enabled modules! $(notdir $(mod_conf)) may need to be generated by using "make conf")
endif
@test -d $(tmpdir) || mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) -s $^ > $@
$(tmpdir)/post_te_files.conf: M4PARAM += -D self_contained_policy
$(tmpdir)/post_te_files.conf: $(m4support) $(tmpdir)/generated_definitions.conf $(base_post_te_files)
@test -d $(tmpdir) || mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) $^ > $@
# extract attributes and put them first. extract post te stuff
# like genfscon and put last.
$(tmpdir)/all_attrs_types.conf: $(tmpdir)/all_te_files.conf
$(verbose) $(get_type_attr_decl) $^ | $(SORT) > $@
$(tmpdir)/all_post.conf: $(tmpdir)/all_te_files.conf $(tmpdir)/post_te_files.conf
$(verbose) cat $(tmpdir)/post_te_files.conf > $@
# these have to run individually because order matters:
$(verbose) $(GREP) '^sid ' $(tmpdir)/all_te_files.conf >> $@ || true
$(verbose) $(GREP) '^fs_use_(xattr|task|trans)' $(tmpdir)/all_te_files.conf >> $@ || true
$(verbose) $(GREP) ^genfscon $(tmpdir)/all_te_files.conf >> $@ || true
$(verbose) $(GREP) ^portcon $(tmpdir)/all_te_files.conf >> $@ || true
$(verbose) $(GREP) ^netifcon $(tmpdir)/all_te_files.conf >> $@ || true
$(verbose) $(GREP) ^nodecon $(tmpdir)/all_te_files.conf >> $@ || true
$(tmpdir)/only_te_rules.conf: $(tmpdir)/all_te_files.conf
$(verbose) $(comment_move_decl) $^ > $@
########################################
#
# Construct a base.fc
#
$(base_fc): $(tmpdir)/$(notdir $(base_fc)).tmp $(fcsort)
$(verbose) $(fcsort) $< $@
$(tmpdir)/$(notdir $(base_fc)).tmp: $(m4support) $(tmpdir)/generated_definitions.conf $(base_fc_files)
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 $(tmpdir) || mkdir -p $(tmpdir)
$(verbose) $(M4) $(M4PARAM) $^ > $@
########################################
#
# Appconfig files
#
$(appdir)/customizable_types: $(base_conf)
$(verbose) $(GREP) '^[[:blank:]]*type .*customizable' $< | cut -d';' -f1 | cut -d',' -f1 | cut -d' ' -f2 | $(SORT) -u > $(tmpdir)/customizable_types
@$(INSTALL) -d -m 0755 $(@D)
$(verbose) $(INSTALL) -m 0644 $(tmpdir)/customizable_types $@
########################################
#
# Validate linking and expanding of modules
#
validate: $(base_pkg) $(mod_pkgs) $(tmpdir)/all_mods.fc
@echo "Validating policy linking."
$(verbose) $(SEMOD_LNK) -o $(tmpdir)/test.lnk $(base_pkg) $(mod_pkgs)
$(verbose) $(SEMOD_EXP) $(tmpdir)/test.lnk $(tmpdir)/policy.bin
@echo "Validating policy file contexts."
$(verbose) $(SETFILES) -q -c $(tmpdir)/policy.bin $(tmpdir)/all_mods.fc
@echo "Success."
########################################
#
# Clean the sources
#
clean:
$(verbose) rm -f $(base_conf)
$(verbose) rm -f $(base_fc)
$(verbose) rm -f $(builddir)*.pp
$(verbose) rm -f $(net_contexts)
$(verbose) rm -fR $(tmpdir)
.PHONY: default all policy base modules install load clean validate