From 04a4549e16c9fa1ec4595e301d586c323e55daf6 Mon Sep 17 00:00:00 2001
From: Jeff Vander Stoep <jeffv@google.com>
Date: Wed, 30 Aug 2017 08:29:01 -0700
Subject: [PATCH] Add test that *_violators attributes are not used

Prevent regression of Treble requirements.

Exempt PRODUCT_FULL_TREBLE_OVERRIDE devices like Marlin. It
was not launched in O-API and is not required to be fully
compliant.

Bug: 65115001
Test: Passes on Marlin. Passes on PRODUCT_FULL_TREBLE device.
    Does not pass if *_violators attributes are locally added.

Change-Id: Ie720adab6ee79148c48880e0562e5bf3704c3e41
---
 Android.mk                     |  8 +++++-
 tests/treble_sepolicy_tests.py | 45 +++++++++++++++++++++++++++++++---
 2 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/Android.mk b/Android.mk
index b666a7eed..a0c51f214 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1265,6 +1265,11 @@ $(treble_sepolicy_tests): PRIVATE_SEPOLICY := $(built_sepolicy)
 $(treble_sepolicy_tests): PRIVATE_SEPOLICY_OLD := $(built_26.0_plat_sepolicy)
 $(treble_sepolicy_tests): PRIVATE_COMBINED_MAPPING := $(26.0_mapping.combined.cil)
 $(treble_sepolicy_tests): PRIVATE_PLAT_SEPOLICY := $(built_plat_sepolicy)
+ifeq ($(PRODUCT_FULL_TREBLE_OVERRIDE),true)
+$(treble_sepolicy_tests): PRIVATE_FAKE_TREBLE := --fake-treble
+else
+$(treble_sepolicy_tests): PRIVATE_FAKE_TREBLE :=
+endif
 $(treble_sepolicy_tests): $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests.py \
 $(built_plat_fc) $(built_nonplat_fc) $(built_sepolicy) $(built_plat_sepolicy) \
 $(built_26.0_plat_sepolicy) $(26.0_compat) $(26.0_mapping.combined.cil)
@@ -1272,7 +1277,8 @@ $(built_26.0_plat_sepolicy) $(26.0_compat) $(26.0_mapping.combined.cil)
 	$(hide) python $(HOST_OUT_EXECUTABLES)/treble_sepolicy_tests.py -l \
 		$(HOST_OUT)/lib64 -f $(PRIVATE_PLAT_FC) -f $(PRIVATE_NONPLAT_FC) \
 		-b $(PRIVATE_PLAT_SEPOLICY) -m $(PRIVATE_COMBINED_MAPPING) \
-		-o $(PRIVATE_SEPOLICY_OLD) -p $(PRIVATE_SEPOLICY)
+		-o $(PRIVATE_SEPOLICY_OLD) -p $(PRIVATE_SEPOLICY) \
+		$(PRIVATE_FAKE_TREBLE)
 	$(hide) touch $@
 
 26.0_PLAT_PUBLIC_POLICY :=
diff --git a/tests/treble_sepolicy_tests.py b/tests/treble_sepolicy_tests.py
index 0e0c0c2c7..2c0cef378 100644
--- a/tests/treble_sepolicy_tests.py
+++ b/tests/treble_sepolicy_tests.py
@@ -76,6 +76,9 @@ alltypes = set()
 oldalltypes = set()
 compatMapping = None
 
+# Distinguish between PRODUCT_FULL_TREBLE and PRODUCT_FULL_TREBLE_OVERRIDE
+FakeTreble = False
+
 def GetAllDomains(pol):
     global alldomains
     for result in pol.QueryTypeAttribute("domain", True):
@@ -172,6 +175,14 @@ def compatSetup(pol, oldpol, mapping):
     GetAllTypes(pol, oldpol)
     compatMapping = mapping
 
+def DomainsWithAttribute(attr):
+    global alldomains
+    domains = []
+    for domain in alldomains:
+        if attr in alldomains[domain].attributes:
+            domains.append(domain)
+    return domains
+
 #############################################################
 # Tests
 #############################################################
@@ -255,6 +266,26 @@ def TestTrebleCompatMapping():
     ret = TestNoUnmappedNewTypes()
     ret += TestNoUnmappedRmTypes()
     return ret
+
+def TestViolatorAttribute(attribute):
+    global FakeTreble
+    ret = ""
+    if FakeTreble:
+        return ret
+
+    violators = DomainsWithAttribute(attribute)
+    if len(violators) > 0:
+        ret += "SELinux: The following domains violate the Treble ban "
+        ret += "against use of the " + attribute + " attribute: "
+        ret += " ".join(str(x) for x in sorted(violators)) + "\n"
+    return ret
+
+def TestViolatorAttributes():
+    ret = TestViolatorAttribute("binder_in_vendor_violators")
+    ret += TestViolatorAttribute("socket_between_core_and_vendor_violators")
+    ret += TestViolatorAttribute("vendor_executes_system_violators")
+    return ret
+
 ###
 # extend OptionParser to allow the same option flag to be used multiple times.
 # This is used to allow multiple file_contexts files and tests to be
@@ -273,11 +304,13 @@ class MultipleOption(Option):
             Option.take_action(self, action, dest, opt, value, values, parser)
 
 Tests = {"CoredomainViolations": TestCoredomainViolations,
-         "TrebleCompatMapping": TestTrebleCompatMapping }
+         "TrebleCompatMapping": TestTrebleCompatMapping,
+         "ViolatorAttributes": TestViolatorAttributes}
 
 if __name__ == '__main__':
-    usage = "treble_sepolicy_tests.py -f nonplat_file_contexts -f "
-    usage +="plat_file_contexts -p curr_policy -b base_policy -o old_policy "
+    usage = "treble_sepolicy_tests.py -l out/host/linux-x86/lib64 "
+    usage += "-f nonplat_file_contexts -f plat_file_contexts "
+    usage += "-p curr_policy -b base_policy -o old_policy "
     usage +="-m mapping file [--test test] [--help]"
     parser = OptionParser(option_class=MultipleOption, usage=usage)
     parser.add_option("-b", "--basepolicy", dest="basepolicy", metavar="FILE")
@@ -288,8 +321,9 @@ if __name__ == '__main__':
     parser.add_option("-o", "--oldpolicy", dest="oldpolicy", metavar="FILE")
     parser.add_option("-p", "--policy", dest="policy", metavar="FILE")
     parser.add_option("-t", "--test", dest="tests", action="extend",
-
             help="Test options include "+str(Tests))
+    parser.add_option("--fake-treble", action="store_true", dest="faketreble",
+            default=False)
 
     (options, args) = parser.parse_args()
 
@@ -317,6 +351,9 @@ if __name__ == '__main__':
             sys.exit("Error: File_contexts file " + f + " does not exist\n" +
                     parser.usage)
 
+    if options.faketreble:
+        FakeTreble = True
+
     pol = policy.Policy(options.policy, options.file_contexts, options.libpath)
     setup(pol)
     basepol = policy.Policy(options.basepolicy, None, options.libpath)
-- 
GitLab