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
This commit is contained in:
Tri Vo 2018-09-28 17:21:08 -07:00
parent da427a33c9
commit e3f4f77d39
4 changed files with 68 additions and 38 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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 $@