From e3f4f77d3924982c23ce4c1dbc43360a1c895938 Mon Sep 17 00:00:00 2001 From: Tri Vo Date: Fri, 28 Sep 2018 17:21:08 -0700 Subject: [PATCH] Don't require private types in mapping file. Private types are not visible to vendor/odm policy, so we don't need mapping entries for them. We build platform-only public policy .cil file and give it as input to treble_sepolicy_tests. Using this public policy the test can now figure out if the newly added type in public or private. Bug: 116344577 Test: adding public type triggers mapping test failure, adding private type does not. Change-Id: I421f335e37274b24aa73109e260653d7b73788b5 --- Android.mk | 22 +++++++++++++++ tests/mini_parser.py | 42 +++++++++++----------------- tests/treble_sepolicy_tests.py | 39 +++++++++++++++++--------- treble_sepolicy_tests_for_release.mk | 3 ++ 4 files changed, 68 insertions(+), 38 deletions(-) diff --git a/Android.mk b/Android.mk index 035977666..4368e4850 100644 --- a/Android.mk +++ b/Android.mk @@ -1610,6 +1610,27 @@ $(built_sepolicy_neverallows) $(hide) cat $(PRIVATE_ADDITIONAL_CIL_FILES) >> $@ $(hide) $(HOST_OUT_EXECUTABLES)/secilc -m -M true -G -c $(POLICYVERS) $(PRIVATE_NEVERALLOW_ARG) $@ -o $@ -f /dev/null +base_plat_pub_policy.conf := $(intermediates)/base_plat_pub_policy.conf +$(base_plat_pub_policy.conf): PRIVATE_MLS_SENS := $(MLS_SENS) +$(base_plat_pub_policy.conf): PRIVATE_MLS_CATS := $(MLS_CATS) +$(base_plat_pub_policy.conf): PRIVATE_TARGET_BUILD_VARIANT := user +$(base_plat_pub_policy.conf): PRIVATE_TGT_ARCH := $(my_target_arch) +$(base_plat_pub_policy.conf): PRIVATE_TGT_WITH_ASAN := $(with_asan) +$(base_plat_pub_policy.conf): PRIVATE_ADDITIONAL_M4DEFS := $(LOCAL_ADDITIONAL_M4DEFS) +$(base_plat_pub_policy.conf): PRIVATE_SEPOLICY_SPLIT := true +$(base_plat_pub_policy.conf): PRIVATE_COMPATIBLE_PROPERTY := $(PRODUCT_COMPATIBLE_PROPERTY) +$(base_plat_pub_policy.conf): $(call build_policy, $(sepolicy_build_files), \ +$(BASE_PLAT_PUBLIC_POLICY) $(REQD_MASK_POLICY)) + $(transform-policy-to-conf) + +base_plat_pub_policy.cil := $(intermediates)/base_plat_pub_policy.cil +$(base_plat_pub_policy.cil): PRIVATE_POL_CONF := $(base_plat_pub_policy.conf) +$(base_plat_pub_policy.cil): PRIVATE_REQD_MASK := $(reqd_policy_mask.cil) +$(base_plat_pub_policy.cil): $(HOST_OUT_EXECUTABLES)/checkpolicy $(base_plat_pub_policy.conf) $(reqd_policy_mask.cil) + @mkdir -p $(dir $@) + $(hide) $(CHECKPOLICY_ASAN_OPTIONS) $< -C -M -c $(POLICYVERS) -o $@.tmp $(PRIVATE_POL_CONF) + $(hide) grep -Fxv -f $(PRIVATE_REQD_MASK) $@.tmp > $@ + all_fc_files := $(built_plat_fc) $(built_vendor_fc) ifdef BOARD_ODM_SEPOLICY_DIRS all_fc_files += $(built_odm_fc) @@ -1630,6 +1651,7 @@ include $(LOCAL_PATH)/treble_sepolicy_tests_for_release.mk BASE_PLAT_PUBLIC_POLICY := BASE_PLAT_PRIVATE_POLICY := base_plat_policy.conf := +base_plat_pub_policy.conf := plat_sepolicy := endif # ($(PRODUCT_SEPOLICY_SPLIT),true) diff --git a/tests/mini_parser.py b/tests/mini_parser.py index 5dfda0695..9182c5d1e 100644 --- a/tests/mini_parser.py +++ b/tests/mini_parser.py @@ -9,12 +9,23 @@ import sys # get the text in the next matching parens class MiniCilParser: - types = set() # types declared in mapping - pubtypes = set() - typeattributes = set() # attributes declared in mapping - typeattributesets = {} # sets defined in mapping - rTypeattributesets = {} # reverse mapping of above sets - apiLevel = None + def __init__(self, policyFile): + self.types = set() # types declared in mapping + self.pubtypes = set() + self.typeattributes = set() # attributes declared in mapping + self.typeattributesets = {} # sets defined in mapping + self.rTypeattributesets = {} # reverse mapping of above sets + self.apiLevel = None + + with open(policyFile, 'r') as infile: + s = self._getNextStmt(infile) + while s: + self._parseStmt(s) + s = self._getNextStmt(infile) + fn = basename(policyFile) + m = re.match(r"(\d+\.\d+).+\.cil", fn) + if m: + self.apiLevel = m.group(1) def _getNextStmt(self, infile): parens = 0 @@ -77,27 +88,8 @@ class MiniCilParser: self._parseTypeattribute(stmt) elif re.match(r"typeattributeset\s+.+", stmt): self._parseTypeattributeset(stmt) - elif re.match(r"expandtypeattribute\s+.+", stmt): - # To silence the build warnings. - pass - else: - m = re.match(r"(\w+)\s+.+", stmt) - ret = "Warning: Unknown statement type (" + m.group(1) + ") in " - ret += "mapping file, perhaps consider adding support for it in " - ret += "system/sepolicy/tests/mini_parser.py!\n" - print ret return - def __init__(self, policyFile): - with open(policyFile, 'r') as infile: - s = self._getNextStmt(infile) - while s: - self._parseStmt(s) - s = self._getNextStmt(infile) - fn = basename(policyFile) - m = re.match(r"(\d+\.\d+).+\.cil", fn) - self.apiLevel = m.group(1) - if __name__ == '__main__': f = sys.argv[1] p = MiniCilParser(f) diff --git a/tests/treble_sepolicy_tests.py b/tests/treble_sepolicy_tests.py index 6e9eb6ad2..05549a1e0 100644 --- a/tests/treble_sepolicy_tests.py +++ b/tests/treble_sepolicy_tests.py @@ -76,6 +76,7 @@ pol = None alltypes = set() oldalltypes = set() compatMapping = None +pubtypes = set() # Distinguish between PRODUCT_FULL_TREBLE and PRODUCT_FULL_TREBLE_OVERRIDE FakeTreble = False @@ -170,11 +171,13 @@ def setup(pol): GetCoreDomains() # setup for the policy compatibility tests -def compatSetup(pol, oldpol, mapping): +def compatSetup(pol, oldpol, mapping, types): global compatMapping + global pubtypes GetAllTypes(pol, oldpol) compatMapping = mapping + pubtypes = types def DomainsWithAttribute(attr): global alldomains @@ -219,24 +222,25 @@ def TestCoredomainViolations(): return ret ### -# Make sure that any new type introduced in the new policy that was not present -# in the old policy has been recorded in the mapping file. +# Make sure that any new public type introduced in the new policy that was not +# present in the old policy has been recorded in the mapping file. def TestNoUnmappedNewTypes(): global alltypes global oldalltypes global compatMapping + global pubtypes newt = alltypes - oldalltypes ret = "" violators = [] for n in newt: - if compatMapping.rTypeattributesets.get(n) is None: + if n in pubtypes and compatMapping.rTypeattributesets.get(n) is None: violators.append(n) if len(violators) > 0: - ret += "SELinux: The following types were found added to the policy " - ret += "without an entry into the compatibility mapping file(s) found " - ret += "in private/compat/" + compatMapping.apiLevel + "/" + ret += "SELinux: The following public types were found added to the " + ret += "policy without an entry into the compatibility mapping file(s) " + ret += "found in private/compat/" + compatMapping.apiLevel + "/" ret += compatMapping.apiLevel + "[.ignore].cil\n" ret += " ".join(str(x) for x in sorted(violators)) + "\n" return ret @@ -322,6 +326,8 @@ if __name__ == '__main__': usage +="-m mapping file [--test test] [--help]" parser = OptionParser(option_class=MultipleOption, usage=usage) parser.add_option("-b", "--basepolicy", dest="basepolicy", metavar="FILE") + parser.add_option("-u", "--base-pub-policy", dest="base_pub_policy", + metavar="FILE") parser.add_option("-f", "--file_contexts", dest="file_contexts", metavar="FILE", action="extend", type="string") parser.add_option("-l", "--library-path", dest="libpath", metavar="FILE") @@ -352,19 +358,26 @@ if __name__ == '__main__': sys.exit("Error: File_contexts file " + f + " does not exist\n" + parser.usage) - # Mapping files are only necessary for the TrebleCompatMapping test + # Mapping files and public platform policy are only necessary for the + # TrebleCompatMapping test. if options.tests is None or options.tests is "TrebleCompatMapping": if not options.basepolicy: - sys.exit("Must specify the current platform-only policy file\n" + parser.usage) + sys.exit("Must specify the current platform-only policy file\n" + + parser.usage) if not options.mapping: - sys.exit("Must specify a compatibility mapping file\n" + parser.usage) + sys.exit("Must specify a compatibility mapping file\n" + + parser.usage) if not options.oldpolicy: - sys.exit("Must specify the previous monolithic policy file\n" + parser.usage) + sys.exit("Must specify the previous monolithic policy file\n" + + parser.usage) + if not options.base_pub_policy: + sys.exit("Must specify the current platform-only public policy " + + ".cil file\n" + parser.usage) basepol = policy.Policy(options.basepolicy, None, options.libpath) oldpol = policy.Policy(options.oldpolicy, None, options.libpath) mapping = mini_parser.MiniCilParser(options.mapping) - compatSetup(basepol, oldpol, mapping) - + pubpol = mini_parser.MiniCilParser(options.base_pub_policy) + compatSetup(basepol, oldpol, mapping, pubpol.types) if options.faketreble: FakeTreble = True diff --git a/treble_sepolicy_tests_for_release.mk b/treble_sepolicy_tests_for_release.mk index 5fb18bff6..1ab29b5fd 100644 --- a/treble_sepolicy_tests_for_release.mk +++ b/treble_sepolicy_tests_for_release.mk @@ -85,6 +85,7 @@ $(treble_sepolicy_tests_$(version)): PRIVATE_SEPOLICY := $(built_sepolicy) $(treble_sepolicy_tests_$(version)): PRIVATE_SEPOLICY_OLD := $(built_$(version)_plat_sepolicy) $(treble_sepolicy_tests_$(version)): PRIVATE_COMBINED_MAPPING := $($(version)_mapping.combined.cil) $(treble_sepolicy_tests_$(version)): PRIVATE_PLAT_SEPOLICY := $(built_plat_sepolicy) +$(treble_sepolicy_tests_$(version)): PRIVATE_PLAT_PUB_SEPOLICY := $(base_plat_pub_policy.cil) $(treble_sepolicy_tests_$(version)): PRIVATE_FAKE_TREBLE := ifeq ($(PRODUCT_FULL_TREBLE_OVERRIDE),true) ifdef PRODUCT_SHIPPING_API_LEVEL @@ -100,12 +101,14 @@ endif # PRODUCT_SHIPPING_API_LEVEL defined endif # PRODUCT_FULL_TREBLE_OVERRIDE = true $(treble_sepolicy_tests_$(version)): $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests \ $(all_fc_files) $(built_sepolicy) $(built_plat_sepolicy) \ + $(base_plat_pub_policy.cil) \ $(built_$(version)_plat_sepolicy) $($(version)_compat) $($(version)_mapping.combined.cil) @mkdir -p $(dir $@) $(hide) $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests -l \ $(HOST_OUT)/lib64/libsepolwrap.$(SHAREDLIB_EXT) $(ALL_FC_ARGS) \ -b $(PRIVATE_PLAT_SEPOLICY) -m $(PRIVATE_COMBINED_MAPPING) \ -o $(PRIVATE_SEPOLICY_OLD) -p $(PRIVATE_SEPOLICY) \ + -u $(PRIVATE_PLAT_PUB_SEPOLICY) \ $(PRIVATE_FAKE_TREBLE) $(hide) touch $@