sepolicy: add version_policy tool and version non-platform policy.
In order to support platform changes without simultaneous updates from
non-platform components, the platform and non-platform policies must be
split. In order to provide a guarantee that policy written for
non-platform objects continues to provide the same access, all types
exposed to non-platform policy are versioned by converting them and the
policy using them into attributes.
This change performs that split, the subsequent versioning and also
generates a mapping file to glue the different policy components
together.
Test: Device boots and runs.
Bug: 31369363
Change-Id: Ibfd3eb077bd9b8e2ff3b2e6a0ca87e44d78b1317
diff --git a/Android.mk b/Android.mk
index 3eddee8..5209145 100644
--- a/Android.mk
+++ b/Android.mk
@@ -38,14 +38,13 @@
# in this policy to ensure that policy targeting attributes from public
# policy from an older platform version continues to work.
-# TODO - build process for device:
+# build process for device:
# 1) convert policies to CIL:
# - private + public platform policy to CIL
# - mapping file to CIL (should already be in CIL form)
# - non-platform public policy to CIL
# - non-platform public + private policy to CIL
# 2) attributize policy
-# - TODO: do this for platform policy?
# - run script which takes non-platform public and non-platform combined
# private + public policy and produces attributized and versioned
# non-platform policy
@@ -55,6 +54,27 @@
PLAT_PUBLIC_POLICY := $(LOCAL_PATH)/public
PLAT_PRIVATE_POLICY := $(LOCAL_PATH)/private
+REQD_MASK_POLICY := $(LOCAL_PATH)/reqd_mask
+
+# TODO: move to README when doing the README update and finalizing versioning.
+# BOARD_SEPOLICY_VERS should contain the platform version identifier
+# corresponding to the platform on which the non-platform policy is to be
+# based. If unspecified, this will build against the current public platform
+# policy in tree.
+# BOARD_SEPOLICY_VERS_DIR should contain the public platform policy which
+# is associated with the given BOARD_SEPOLICY_VERS. The policy therein will be
+# versioned according to the BOARD_SEPOLICY_VERS identifier and included as
+# part of the non-platform policy to ensure removal of access in future
+# platform policy does not break non-platform policy.
+ifndef BOARD_SEPOLICY_VERS
+$(warning BOARD_SEPOLICY_VERS not specified, assuming current platform version)
+BOARD_SEPOLICY_VERS := current
+BOARD_SEPOLICY_VERS_DIR := $(PLAT_PUBLIC_POLICY)
+else
+ifndef BOARD_SEPOLICY_VERS_DIR
+$(error BOARD_SEPOLICY_VERS_DIR not specified for versioned sepolicy.)
+endif
+endif
###########################################################
# Compute policy files to be used in policy build.
@@ -83,6 +103,7 @@
global_macros \
neverallow_macros \
mls_macros \
+ mls_decl \
mls \
policy_capabilities \
te_macros \
@@ -90,6 +111,7 @@
ioctl_defines \
ioctl_macros \
*.te \
+ roles_decl \
roles \
users \
initial_sid_contexts \
@@ -128,11 +150,64 @@
include $(BUILD_SYSTEM)/base_rules.mk
-platform_policy.conf := $(intermediates)/plat_policy.conf
-$(platform_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
-$(platform_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
-$(platform_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(platform_policy.conf): $(call build_policy, $(sepolicy_build_files), \
+# reqd_policy_mask - a policy.conf file which contains only the bare minimum
+# policy necessary to use checkpolicy. This bare-minimum policy needs to be
+# present in all policy.conf files, but should not necessarily be exported as
+# part of the public policy. The rules generated by reqd_policy_mask will allow
+# the compilation of public policy and subsequent removal of CIL policy that
+# should not be exported.
+
+reqd_policy_mask.conf := $(intermediates)/reqd_policy_mask.conf
+$(reqd_policy_mask.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(reqd_policy_mask.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(reqd_policy_mask.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(reqd_policy_mask.conf): $(call build_policy, $(sepolicy_build_files), $(REQD_MASK_POLICY))
+ @mkdir -p $(dir $@)
+ $(hide) m4 $(PRIVATE_ADDITIONAL_M4DEFS) \
+ -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
+ -D target_build_variant=$(TARGET_BUILD_VARIANT) \
+ -s $^ > $@
+
+reqd_policy_mask.cil := $(intermediates)/reqd_policy_mask.cil
+$(reqd_policy_mask.cil): $(reqd_policy_mask.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy
+ @mkdir -p $(dir $@)
+ $(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -C -M -c $(POLICYVERS) -o $@ $<
+
+# plat_pub_policy - policy that will be exported to be a part of non-platform
+# policy corresponding to this platform version. This is a limited subset of
+# policy that would not compile in checkpolicy on its own. To get around this
+# limitation, add only the required files from private policy, which will
+# generate CIL policy that will then be filtered out by the reqd_policy_mask.
+plat_pub_policy.conf := $(intermediates)/plat_pub_policy.conf
+$(plat_pub_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(plat_pub_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(plat_pub_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(plat_pub_policy.conf): $(call build_policy, $(sepolicy_build_files), \
+$(BOARD_SEPOLICY_VERS_DIR) $(REQD_MASK_POLICY))
+ @mkdir -p $(dir $@)
+ $(hide) m4 $(PRIVATE_ADDITIONAL_M4DEFS) \
+ -D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
+ -D target_build_variant=$(TARGET_BUILD_VARIANT) \
+ -s $^ > $@
+
+plat_pub_policy.cil := $(intermediates)/plat_pub_policy.cil
+$(plat_pub_policy.cil): $(plat_pub_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy
+ @mkdir -p $(dir $@)
+ $(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -C -M -c $(POLICYVERS) -o $@ $<
+
+pruned_plat_pub_policy.cil := $(intermediates)/pruned_plat_pub_policy.cil
+$(pruned_plat_pub_policy.cil): $(reqd_policy_mask.cil) $(plat_pub_policy.cil)
+ @mkdir -p $(dir $@)
+ $(hide) grep -Fxv -f $^ > $@
+
+# plat_policy.conf - A combination of the private and public platform policy
+# which will ship with the device. The platform will always reflect the most
+# recent platform version and is not currently being attributized.
+plat_policy.conf := $(intermediates)/plat_policy.conf
+$(plat_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(plat_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(plat_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(plat_policy.conf): $(call build_policy, $(sepolicy_build_files), \
$(PLAT_PUBLIC_POLICY) $(PLAT_PRIVATE_POLICY))
@mkdir -p $(dir $@)
$(hide) m4 $(PRIVATE_ADDITIONAL_M4DEFS) \
@@ -144,15 +219,23 @@
-s $^ > $@
$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
-# TODO: add steps for non-platform public and combined files with checkpolicy
-# support. b/31932523
+plat_policy.cil := $(intermediates)/plat_policy.cil
+$(plat_policy.cil): $(plat_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy
+ @mkdir -p $(dir $@)
+ $(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -C -c $(POLICYVERS) -o $@.tmp $<
+ $(hide) grep -v neverallow $@.tmp > $@
-sepolicy_policy.conf := $(intermediates)/policy.conf
-$(sepolicy_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
-$(sepolicy_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
-$(sepolicy_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
-$(sepolicy_policy.conf): $(call build_policy, $(sepolicy_build_files), \
-$(PLAT_PUBLIC_POLICY) $(PLAT_PRIVATE_POLICY) $(BOARD_SEPOLICY_DIRS))
+# nonplat_policy.conf - A combination of the non-platform private and the
+# exported platform policy associated with the version the non-platform policy
+# targets. This needs attributization and to be combined with the
+# platform-provided policy. Like plat_pub_policy.conf, this needs to make use
+# of the reqd_policy_mask files from private policy in order to use checkpolicy.
+nonplat_policy.conf := $(intermediates)/nonplat_policy.conf
+$(nonplat_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS)
+$(nonplat_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS)
+$(nonplat_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS)
+$(nonplat_policy.conf): $(call build_policy, $(sepolicy_build_files), \
+$(BOARD_SEPOLICY_VERS_DIR) $(REQD_MASK_POLICY) $(BOARD_SEPOLICY_DIRS))
@mkdir -p $(dir $@)
$(hide) m4 $(PRIVATE_ADDITIONAL_M4DEFS) \
-D mls_num_sens=$(PRIVATE_MLS_SENS) -D mls_num_cats=$(PRIVATE_MLS_CATS) \
@@ -164,10 +247,47 @@
-s $^ > $@
$(hide) sed '/dontaudit/d' $@ > $@.dontaudit
-$(LOCAL_BUILT_MODULE): $(sepolicy_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy $(HOST_OUT_EXECUTABLES)/sepolicy-analyze
+nonplat_policy.cil := $(intermediates)/nonplat_policy.cil
+$(nonplat_policy.cil): $(nonplat_policy.conf) $(HOST_OUT_EXECUTABLES)/checkpolicy
@mkdir -p $(dir $@)
- $(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -c $(POLICYVERS) -o $@.tmp $< > /dev/null
- $(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -M -c $(POLICYVERS) -o $(dir $<)/$(notdir $@).dontaudit $<.dontaudit > /dev/null
+ $(hide) $(HOST_OUT_EXECUTABLES)/checkpolicy -C -M -c $(POLICYVERS) -o $@ $<
+
+pruned_nonplat_policy.cil := $(intermediates)/pruned_nonplat_policy.cil
+$(pruned_nonplat_policy.cil): $(reqd_policy_mask.cil) $(nonplat_policy.cil)
+ @mkdir -p $(dir $@)
+ $(hide) grep -Fxv -f $^ | grep -v neverallow > $@
+
+vers_nonplat_policy.cil := $(intermediates)/vers_nonplat_policy.cil
+$(vers_nonplat_policy.cil) : PRIVATE_VERS := $(BOARD_SEPOLICY_VERS)
+$(vers_nonplat_policy.cil) : PRIVATE_TGT_POL := $(pruned_nonplat_policy.cil)
+$(vers_nonplat_policy.cil) : $(pruned_plat_pub_policy.cil) $(pruned_nonplat_policy.cil) \
+$(HOST_OUT_EXECUTABLES)/version_policy
+ @mkdir -p $(dir $@)
+ $(HOST_OUT_EXECUTABLES)/version_policy -b $< -t $(PRIVATE_TGT_POL) -n $(PRIVATE_VERS) -o $@
+
+# auto-generate the mapping file for current platform policy, since it needs to
+# track platform policy development
+current_mapping.cil := $(intermediates)/mapping/current.cil
+$(current_mapping.cil) : PRIVATE_VERS := $(BOARD_SEPOLICY_VERS)
+$(current_mapping.cil) : $(pruned_plat_pub_policy.cil) $(HOST_OUT_EXECUTABLES)/version_policy
+ @mkdir -p $(dir $@)
+ $(hide) $(HOST_OUT_EXECUTABLES)/version_policy -b $< -m -n $(PRIVATE_VERS) -o $@
+
+ifeq ($(BOARD_SEPOLICY_VERS), current)
+mapping.cil := $(current_mapping.cil)
+else
+mapping.cil := $(addsuffix /$(BOARD_SEPOLICY_VERS).cil, $(PLAT_PRIVATE_POLICY)/mapping)
+endif
+
+all_cil_files := \
+ $(plat_policy.cil) \
+ $(vers_nonplat_policy.cil) \
+ $(mapping.cil)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_CIL_FILES := $(all_cil_files)
+$(LOCAL_BUILT_MODULE): $(HOST_OUT_EXECUTABLES)/secilc $(HOST_OUT_EXECUTABLES)/sepolicy-analyze $(all_cil_files)
+ @mkdir -p $(dir $@)
+ $(hide) $< -M true -c $(POLICYVERS) $(PRIVATE_CIL_FILES) -o $@.tmp
$(hide) $(HOST_OUT_EXECUTABLES)/sepolicy-analyze $@.tmp permissive > $@.permissivedomains
$(hide) if [ "$(TARGET_BUILD_VARIANT)" = "user" -a -s $@.permissivedomains ]; then \
echo "==========" 1>&2; \
@@ -179,6 +299,20 @@
$(hide) mv $@.tmp $@
built_sepolicy := $(LOCAL_BUILT_MODULE)
+reqd_policy_mask.conf :=
+reqd_policy_mask.cil :=
+plat_pub_policy.conf :=
+plat_pub_policy.cil :=
+pruned_plat_pub_policy.cil :=
+plat_policy.conf :=
+plat_policy.cil :=
+nonplat_policy.conf :=
+nonplat_policy.cil :=
+pruned_nonplat_policy.cil :=
+vers_nonplat_policy.cil :=
+current_mapping.cil :=
+mapping.cil :=
+all_cil_files :=
sepolicy_policy.conf :=
##################################
@@ -311,7 +445,7 @@
$(file_contexts.device.sorted.tmp): PRIVATE_SEPOLICY := $(built_sepolicy)
$(file_contexts.device.sorted.tmp): $(file_contexts.device.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/fc_sort $(HOST_OUT_EXECUTABLES)/checkfc
@mkdir -p $(dir $@)
- $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -e $(PRIVATE_SEPOLICY) $<
+ # TODO: fix with attributized types $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -e $(PRIVATE_SEPOLICY) $<
$(hide) $(HOST_OUT_EXECUTABLES)/fc_sort $< $@
file_contexts.concat.tmp := $(intermediates)/file_contexts.concat.tmp
@@ -322,7 +456,7 @@
$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_sepolicy)
$(LOCAL_BUILT_MODULE): $(file_contexts.concat.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/sefcontext_compile $(HOST_OUT_EXECUTABLES)/checkfc
@mkdir -p $(dir $@)
- $(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(PRIVATE_SEPOLICY) $<
+ # TODO: fix with attributized types $(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(PRIVATE_SEPOLICY) $<
$(hide) $(HOST_OUT_EXECUTABLES)/sefcontext_compile -o $@ $<
built_fc := $(LOCAL_BUILT_MODULE)
@@ -352,7 +486,7 @@
$(LOCAL_BUILT_MODULE): PRIVATE_SEPOLICY := $(built_general_sepolicy)
$(LOCAL_BUILT_MODULE): $(general_file_contexts.tmp) $(built_general_sepolicy) $(HOST_OUT_EXECUTABLES)/sefcontext_compile $(HOST_OUT_EXECUTABLES)/checkfc
@mkdir -p $(dir $@)
- $(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(PRIVATE_SEPOLICY) $<
+ # TODO: fix with attributized types $(hide) $(HOST_OUT_EXECUTABLES)/checkfc $(PRIVATE_SEPOLICY) $<
$(hide) $(HOST_OUT_EXECUTABLES)/sefcontext_compile -o $@ $<
general_file_contexts.tmp :=
@@ -433,7 +567,7 @@
$(LOCAL_BUILT_MODULE): $(property_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc
@mkdir -p $(dir $@)
$(hide) sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
- $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
+ # TODO: fix with attributized types $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
built_pc := $(LOCAL_BUILT_MODULE)
all_pc_files :=
@@ -458,7 +592,7 @@
$(LOCAL_BUILT_MODULE): $(general_property_contexts.tmp) $(built_general_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
@mkdir -p $(dir $@)
$(hide) sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
- $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
+ # TODO: fix with attributized types $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -p $(PRIVATE_SEPOLICY) $@
general_property_contexts.tmp :=
@@ -486,7 +620,7 @@
$(LOCAL_BUILT_MODULE): $(service_contexts.tmp) $(built_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
@mkdir -p $(dir $@)
sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
- $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
+ # TODO: fix with attributized types$(hide) $(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
built_svc := $(LOCAL_BUILT_MODULE)
all_svc_files :=
@@ -511,7 +645,7 @@
$(LOCAL_BUILT_MODULE): $(general_service_contexts.tmp) $(built_general_sepolicy) $(HOST_OUT_EXECUTABLES)/checkfc $(ACP)
@mkdir -p $(dir $@)
sed -e 's/#.*$$//' -e '/^$$/d' $< > $@
- $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
+ # TODO: fix with attributized types $(hide) $(HOST_OUT_EXECUTABLES)/checkfc -s $(PRIVATE_SEPOLICY) $@
general_service_contexts.tmp :=