Merge "Adding netd and authorization fuzzers to bindings"
diff --git a/build/soong/build_files.go b/build/soong/build_files.go
index 383a282..ed92f1a 100644
--- a/build/soong/build_files.go
+++ b/build/soong/build_files.go
@@ -80,7 +80,7 @@
 		return paths, nil
 	}
 
-	return nil, fmt.Errorf("unknown tag %q. Supported tags are: %q", tag, strings.Join(android.SortedStringKeys(b.srcs), " "))
+	return nil, fmt.Errorf("unknown tag %q. Supported tags are: %q", tag, strings.Join(android.SortedKeys(b.srcs), " "))
 }
 
 var _ android.OutputFileProducer = (*buildFiles)(nil)
diff --git a/microdroid/system/private/domain.te b/microdroid/system/private/domain.te
index 4251a9e..5482b01 100644
--- a/microdroid/system/private/domain.te
+++ b/microdroid/system/private/domain.te
@@ -208,6 +208,7 @@
 get_prop(domain, arm64_memtag_prop)
 get_prop(domain, bootloader_prop)
 get_prop(domain, build_prop)
+get_prop(domain, debuggable_prop)
 get_prop(domain, debug_prop)
 get_prop(domain, fingerprint_prop)
 get_prop(domain, init_service_status_prop)
@@ -391,6 +392,7 @@
 neverallow { domain -init -vendor_init } vendor_default_prop:property_service set;
 
 neverallow { domain -init } build_prop:property_service set;
+neverallow { domain -init -init_debug_policy } debuggable_prop:property_service set;
 
 # Never allow anyone to connect or write to
 # the tombstoned intercept socket.
diff --git a/microdroid/system/private/file_contexts b/microdroid/system/private/file_contexts
index 8d9ad85..63221ce 100644
--- a/microdroid/system/private/file_contexts
+++ b/microdroid/system/private/file_contexts
@@ -106,6 +106,7 @@
 /system/bin/bootstrap/linker(64)? u:object_r:system_linker_exec:s0
 /system/bin/bootstrap/linkerconfig u:object_r:linkerconfig_exec:s0
 /system/bin/init		u:object_r:init_exec:s0
+/system/bin/init_debug_policy	u:object_r:init_debug_policy_exec:s0
 /system/bin/logcat	--	u:object_r:logcat_exec:s0
 /system/bin/logd        u:object_r:logd_exec:s0
 /system/bin/sh		--	u:object_r:shell_exec:s0
diff --git a/microdroid/system/private/genfs_contexts b/microdroid/system/private/genfs_contexts
index ce28471..f55711e 100644
--- a/microdroid/system/private/genfs_contexts
+++ b/microdroid/system/private/genfs_contexts
@@ -137,6 +137,7 @@
 genfscon sysfs /devices/virtual/net             u:object_r:sysfs_net:s0
 genfscon sysfs /devices/virtual/switch          u:object_r:sysfs_switch:s0
 genfscon sysfs /devices/virtual/wakeup          u:object_r:sysfs_wakeup:s0
+genfscon sysfs /firmware/devicetree/base/avf u:object_r:sysfs_dt_avf:s0
 genfscon sysfs /firmware/devicetree/base/chosen/avf,new-instance u:object_r:sysfs_dt_avf:s0
 genfscon sysfs /firmware/devicetree/base/chosen/avf,strict-boot u:object_r:sysfs_dt_avf:s0
 genfscon sysfs /firmware/devicetree/base/firmware/android u:object_r:sysfs_dt_firmware_android:s0
diff --git a/microdroid/system/private/init_debug_policy.te b/microdroid/system/private/init_debug_policy.te
new file mode 100644
index 0000000..33b8917
--- /dev/null
+++ b/microdroid/system/private/init_debug_policy.te
@@ -0,0 +1,32 @@
+# init_debug_policy is its own domain.
+type init_debug_policy, domain, coredomain;
+type init_debug_policy_exec, system_file_type, exec_type, file_type;
+
+# Transition from init -> init_debug_policy_exec
+init_daemon_domain(init_debug_policy);
+
+# init_debug_policy is using bootstrap bionic
+use_bootstrap_libs(init_debug_policy)
+
+# Allow init_debug_policy to write /dev/kmsg (specified by stdio_to_kmsg)
+allow init_debug_policy kmsg_debug_device:chr_file w_file_perms;
+
+# Allow init_debug_policy to use xxd and set/getprop
+allow init_debug_policy toolbox_exec:file rx_file_perms;
+
+# Allow init_debug_policy to set ro.debuggable to enable/disable adb root
+set_prop(init_debug_policy, debuggable_prop)
+
+# Allow init_debug_policy to set ro.log.file_logger.path to enable/disable console log
+set_prop(init_debug_policy, log_prop)
+
+# Allow init_debug_policy to get ro.boot.microdroid.debuggable and ro.boot.adb.enabled
+get_prop(init_debug_policy, bootloader_prop)
+
+# Allow init_debug_policy to set init_debug_policy.adbd.enabled
+set_prop(init_debug_policy, init_debug_policy_prop)
+
+# Allow init_debug_policy to read AVF debug policy
+allow init_debug_policy sysfs_dt_avf:dir search;
+allow init_debug_policy sysfs_dt_avf:file { open read };
+
diff --git a/microdroid/system/private/property_contexts b/microdroid/system/private/property_contexts
index 235ab14..bb43d58 100644
--- a/microdroid/system/private/property_contexts
+++ b/microdroid/system/private/property_contexts
@@ -108,10 +108,11 @@
 ro.build.version.sdk            u:object_r:build_prop:s0 exact int
 ro.build.version.security_patch u:object_r:build_prop:s0 exact string
 ro.build.version.known_codenames u:object_r:build_prop:s0 exact string
-ro.debuggable                   u:object_r:build_prop:s0 exact bool
 ro.product.cpu.abilist          u:object_r:build_prop:s0 exact string
 ro.adb.secure                   u:object_r:build_prop:s0 exact bool
 
+ro.debuggable                   u:object_r:debuggable_prop:s0 exact bool
+
 ro.property_service.version u:object_r:property_service_version_prop:s0 exact int
 
 apex_config.done u:object_r:apex_config_prop:s0 exact bool
@@ -125,6 +126,8 @@
 microdroid_manager.config_done u:object_r:microdroid_lifecycle_prop:s0 exact bool
 microdroid_manager.init_done u:object_r:microdroid_lifecycle_prop:s0 exact bool
 
+init_debug_policy.adbd.enabled u:object_r:init_debug_policy_prop:s0 exact bool
+
 dev.mnt.blk.root   u:object_r:dev_mnt_prop:s0 exact string
 dev.mnt.blk.vendor u:object_r:dev_mnt_prop:s0 exact string
 dev.mnt.dev.root   u:object_r:dev_mnt_prop:s0 exact string
diff --git a/microdroid/system/public/property.te b/microdroid/system/public/property.te
index a2c3b77..158d741 100644
--- a/microdroid/system/public/property.te
+++ b/microdroid/system/public/property.te
@@ -6,6 +6,7 @@
 type bootloader_prop, property_type;
 type boottime_prop, property_type;
 type build_prop, property_type;
+type debuggable_prop, property_type;
 type cold_boot_done_prop, property_type;
 type ctl_adbd_prop, property_type;
 type ctl_apexd_prop, property_type;
@@ -35,6 +36,7 @@
 type init_service_status_private_prop, property_type;
 type init_service_status_prop, property_type;
 type init_svc_debug_prop, property_type;
+type init_debug_policy_prop, property_type;
 type libc_debug_prop, property_type;
 type log_prop, property_type;
 type log_tag_prop, property_type;
diff --git a/private/property.te b/private/property.te
index 4f806d4..4fd9bc3 100644
--- a/private/property.te
+++ b/private/property.te
@@ -632,6 +632,7 @@
   domain
   -init
   -remote_prov_app
+  -shell
 } remote_prov_prop:property_service set;
 
 neverallow {
diff --git a/private/property_contexts b/private/property_contexts
index 2db9da6..4ce654c 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -872,6 +872,7 @@
 # Populated on Android Studio Emulator (for emulator specific workarounds)
 ro.boot.qemu               u:object_r:bootloader_prop:s0 exact bool
 ro.boot.revision           u:object_r:bootloader_prop:s0 exact string
+ro.boot.serialconsole      u:object_r:bootloader_prop:s0 exact bool
 ro.boot.vbmeta.avb_version u:object_r:bootloader_prop:s0 exact string
 ro.boot.verifiedbootstate  u:object_r:bootloader_prop:s0 exact string
 ro.boot.veritymode         u:object_r:bootloader_prop:s0 exact string
diff --git a/private/shell.te b/private/shell.te
index 02105a9..cdbf7c2 100644
--- a/private/shell.te
+++ b/private/shell.te
@@ -101,6 +101,9 @@
 # Allow shell to set this property used for rollback tests
 set_prop(shell, rollback_test_prop)
 
+# Allow shell to set RKP properties for testing purposes
+set_prop(shell, remote_prov_prop)
+
 # Allow shell to get encryption policy of /data/local/tmp/, for CTS
 allowxperm shell shell_data_file:dir ioctl {
   FS_IOC_GET_ENCRYPTION_POLICY
diff --git a/private/system_server.te b/private/system_server.te
index b3c7528..27e5594 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -102,10 +102,12 @@
 allow system_server zygote:fd use;
 allow system_server zygote:process sigchld;
 
-# May kill zygote on crashes.
+# May kill zygote (or its child processes) on crashes.
 allow system_server {
   app_zygote
   crash_dump
+  crosvm
+  virtualizationmanager
   webview_zygote
   zygote
 }:process { getpgid sigkill signull };
@@ -840,7 +842,7 @@
 set_prop(system_server, tuner_server_ctl_prop)
 
 # Allow the heap dump ART plugin to the count of sessions waiting for OOME
-get_prop(appdomain, traced_oome_heap_session_count_prop)
+get_prop(system_server, traced_oome_heap_session_count_prop)
 
 # Create a socket for connections from debuggerd.
 allow system_server system_ndebug_socket:sock_file create_file_perms;
diff --git a/private/technical_debt.cil b/private/technical_debt.cil
index 27ea187..485ce53 100644
--- a/private/technical_debt.cil
+++ b/private/technical_debt.cil
@@ -47,7 +47,7 @@
 ; Apps, except isolated apps, are clients of Neuralnetworks HAL
 ; Unfortunately, we can't currently express this in module policy language:
 ;     typeattribute { appdomain -isolated_app_all } hal_neuralnetworks_client;
-(typeattributeset hal_neuralnetworks_client ((and (appdomain) ((not (isolated_app_all))))))
+(typeattributeset hal_neuralnetworks_client ((and (appdomain) ((not (isolated_app))))))
 
 ; TODO(b/112056006): move these to mapping files when/if we implement 'versioned' attributes.
 ; Rename untrusted_app_visible_* to untrusted_app_visible_*_violators.
diff --git a/public/hal_wifi.te b/public/hal_wifi.te
index e4f1d21..a0826bb 100644
--- a/public/hal_wifi.te
+++ b/public/hal_wifi.te
@@ -5,7 +5,7 @@
 hal_attribute_hwservice(hal_wifi, hal_wifi_hwservice)
 hal_attribute_service(hal_wifi, hal_wifi_service)
 
-binder_call(hal_wifi_server, servicemanager)
+binder_use(hal_wifi_server)
 
 r_dir_file(hal_wifi, proc_net_type)
 r_dir_file(hal_wifi, sysfs_type)
diff --git a/public/service.te b/public/service.te
index 1f86ff2..82a713a 100644
--- a/public/service.te
+++ b/public/service.te
@@ -234,7 +234,7 @@
 type texttospeech_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type telecom_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type thermal_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
-type timedetector_service, app_api_service, system_server_service, service_manager_type;
+type timedetector_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type timezonedetector_service, app_api_service, system_server_service, service_manager_type;
 type translation_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type trust_service, app_api_service, system_server_service, service_manager_type;
diff --git a/tests/treble_sepolicy_tests.py b/tests/treble_sepolicy_tests.py
index b49f138..c966423 100644
--- a/tests/treble_sepolicy_tests.py
+++ b/tests/treble_sepolicy_tests.py
@@ -51,172 +51,166 @@
         self.entrypointpaths = []
         self.error = ""
 
-def PrintScontexts():
-    for d in sorted(alldomains.keys()):
-        sctx = alldomains[d]
-        print(d)
-        print("\tcoredomain="+str(sctx.coredomain))
-        print("\tappdomain="+str(sctx.appdomain))
-        print("\tfromSystem="+str(sctx.fromSystem))
-        print("\tfromVendor="+str(sctx.fromVendor))
-        print("\tattributes="+str(sctx.attributes))
-        print("\tentrypoints="+str(sctx.entrypoints))
-        print("\tentrypointpaths=")
-        if sctx.entrypointpaths is not None:
-            for path in sctx.entrypointpaths:
-                print("\t\t"+str(path))
 
-alldomains = {}
-coredomains = set()
-appdomains = set()
-vendordomains = set()
-pol = None
+class TestPolicy:
+    """A policy loaded in memory with its domains easily accessible."""
 
-# compat vars
-alltypes = set()
-oldalltypes = set()
-compatMapping = None
-pubtypes = set()
+    def __init__(self):
+        self.alldomains = {}
+        self.coredomains = set()
+        self.appdomains = set()
+        self.vendordomains = set()
+        self.pol = None
 
-# Distinguish between PRODUCT_FULL_TREBLE and PRODUCT_FULL_TREBLE_OVERRIDE
-FakeTreble = False
+        # compat vars
+        self.alltypes = set()
+        self.oldalltypes = set()
+        self.compatMapping = None
+        self.pubtypes = set()
 
-def GetAllDomains(pol):
-    global alldomains
-    for result in pol.QueryTypeAttribute("domain", True):
-        alldomains[result] = scontext()
+        # Distinguish between PRODUCT_FULL_TREBLE and PRODUCT_FULL_TREBLE_OVERRIDE
+        self.FakeTreble = False
 
-def GetAppDomains():
-    global appdomains
-    global alldomains
-    for d in alldomains:
-        # The application of the "appdomain" attribute is trusted because core
-        # selinux policy contains neverallow rules that enforce that only zygote
-        # and runas spawned processes may transition to processes that have
-        # the appdomain attribute.
-        if "appdomain" in alldomains[d].attributes:
-            alldomains[d].appdomain = True
-            appdomains.add(d)
+    def GetAllDomains(self):
+        for result in self.pol.QueryTypeAttribute("domain", True):
+            self.alldomains[result] = scontext()
 
-def GetCoreDomains():
-    global alldomains
-    global coredomains
-    for d in alldomains:
-        domain = alldomains[d]
-        # TestCoredomainViolations will verify if coredomain was incorrectly
-        # applied.
-        if "coredomain" in domain.attributes:
-            domain.coredomain = True
-            coredomains.add(d)
-        # check whether domains are executed off of /system or /vendor
-        if d in coredomainAllowlist:
-            continue
-        # TODO(b/153112003): add checks to prevent app domains from being
-        # incorrectly labeled as coredomain. Apps don't have entrypoints as
-        # they're always dynamically transitioned to by zygote.
-        if d in appdomains:
-            continue
-        # TODO(b/153112747): need to handle cases where there is a dynamic
-        # transition OR there happens to be no context in AOSP files.
-        if not domain.entrypointpaths:
-            continue
+    def GetAppDomains(self):
+        for d in self.alldomains:
+            # The application of the "appdomain" attribute is trusted because core
+            # selinux policy contains neverallow rules that enforce that only zygote
+            # and runas spawned processes may transition to processes that have
+            # the appdomain attribute.
+            if "appdomain" in self.alldomains[d].attributes:
+                self.alldomains[d].appdomain = True
+                self.appdomains.add(d)
 
-        for path in domain.entrypointpaths:
-            vendor = any(MatchPathPrefix(path, prefix) for prefix in
-                         ["/vendor", "/odm"])
-            system = any(MatchPathPrefix(path, prefix) for prefix in
-                         ["/init", "/system_ext", "/product" ])
+    def GetCoreDomains(self):
+        for d in self.alldomains:
+            domain = self.alldomains[d]
+            # TestCoredomainViolations will verify if coredomain was incorrectly
+            # applied.
+            if "coredomain" in domain.attributes:
+                domain.coredomain = True
+                self.coredomains.add(d)
+            # check whether domains are executed off of /system or /vendor
+            if d in coredomainAllowlist:
+                continue
+            # TODO(b/153112003): add checks to prevent app domains from being
+            # incorrectly labeled as coredomain. Apps don't have entrypoints as
+            # they're always dynamically transitioned to by zygote.
+            if d in self.appdomains:
+                continue
+            # TODO(b/153112747): need to handle cases where there is a dynamic
+            # transition OR there happens to be no context in AOSP files.
+            if not domain.entrypointpaths:
+                continue
 
-            # only mark entrypoint as system if it is not in legacy /system/vendor
-            if MatchPathPrefix(path, "/system/vendor"):
-                vendor = True
-            elif MatchPathPrefix(path, "/system"):
-                system = True
+            for path in domain.entrypointpaths:
+                vendor = any(MatchPathPrefix(path, prefix) for prefix in
+                             ["/vendor", "/odm"])
+                system = any(MatchPathPrefix(path, prefix) for prefix in
+                             ["/init", "/system_ext", "/product" ])
 
-            if not vendor and not system:
-                domain.error += "Unrecognized entrypoint for " + d + " at " + path + "\n"
+                # only mark entrypoint as system if it is not in legacy /system/vendor
+                if MatchPathPrefix(path, "/system/vendor"):
+                    vendor = True
+                elif MatchPathPrefix(path, "/system"):
+                    system = True
 
-            domain.fromSystem = domain.fromSystem or system
-            domain.fromVendor = domain.fromVendor or vendor
+                if not vendor and not system:
+                    domain.error += "Unrecognized entrypoint for " + d + " at " + path + "\n"
 
-###
-# Add the entrypoint type and path(s) to each domain.
-#
-def GetDomainEntrypoints(pol):
-    global alldomains
-    for x in pol.QueryExpandedTERule(tclass=set(["file"]), perms=set(["entrypoint"])):
-        if not x.sctx in alldomains:
-            continue
-        alldomains[x.sctx].entrypoints.append(str(x.tctx))
-        # postinstall_file represents a special case specific to A/B OTAs.
-        # Update_engine mounts a partition and relabels it postinstall_file.
-        # There is no file_contexts entry associated with postinstall_file
-        # so skip the lookup.
-        if x.tctx == "postinstall_file":
-            continue
-        entrypointpath = pol.QueryFc(x.tctx)
-        if not entrypointpath:
-            continue
-        alldomains[x.sctx].entrypointpaths.extend(entrypointpath)
-###
-# Get attributes associated with each domain
-#
-def GetAttributes(pol):
-    global alldomains
-    for domain in alldomains:
-        for result in pol.QueryTypeAttribute(domain, False):
-            alldomains[domain].attributes.add(result)
+                domain.fromSystem = domain.fromSystem or system
+                domain.fromVendor = domain.fromVendor or vendor
 
-def GetAllTypes(pol, oldpol):
-    global alltypes
-    global oldalltypes
-    alltypes = pol.GetAllTypes(False)
-    oldalltypes = oldpol.GetAllTypes(False)
+    ###
+    # Add the entrypoint type and path(s) to each domain.
+    #
+    def GetDomainEntrypoints(self):
+        for x in self.pol.QueryExpandedTERule(tclass=set(["file"]), perms=set(["entrypoint"])):
+            if not x.sctx in self.alldomains:
+                continue
+            self.alldomains[x.sctx].entrypoints.append(str(x.tctx))
+            # postinstall_file represents a special case specific to A/B OTAs.
+            # Update_engine mounts a partition and relabels it postinstall_file.
+            # There is no file_contexts entry associated with postinstall_file
+            # so skip the lookup.
+            if x.tctx == "postinstall_file":
+                continue
+            entrypointpath = self.pol.QueryFc(x.tctx)
+            if not entrypointpath:
+                continue
+            self.alldomains[x.sctx].entrypointpaths.extend(entrypointpath)
 
-def setup(pol):
-    GetAllDomains(pol)
-    GetAttributes(pol)
-    GetDomainEntrypoints(pol)
-    GetAppDomains()
-    GetCoreDomains()
+    ###
+    # Get attributes associated with each domain
+    #
+    def GetAttributes(self):
+        for domain in self.alldomains:
+            for result in self.pol.QueryTypeAttribute(domain, False):
+                self.alldomains[domain].attributes.add(result)
 
-# setup for the policy compatibility tests
-def compatSetup(pol, oldpol, mapping, types):
-    global compatMapping
-    global pubtypes
+    def setup(self, pol):
+        self.pol = pol
+        self.GetAllDomains()
+        self.GetAttributes()
+        self.GetDomainEntrypoints()
+        self.GetAppDomains()
+        self.GetCoreDomains()
 
-    GetAllTypes(pol, oldpol)
-    compatMapping = mapping
-    pubtypes = types
+    def GetAllTypes(self, basepol, oldpol):
+        self.alltypes = basepol.GetAllTypes(False)
+        self.oldalltypes = oldpol.GetAllTypes(False)
 
-def DomainsWithAttribute(attr):
-    global alldomains
-    domains = []
-    for domain in alldomains:
-        if attr in alldomains[domain].attributes:
-            domains.append(domain)
-    return domains
+    # setup for the policy compatibility tests
+    def compatSetup(self, basepol, oldpol, mapping, types):
+        self.GetAllTypes(basepol, oldpol)
+        self.compatMapping = mapping
+        self.pubtypes = types
+
+    def DomainsWithAttribute(self, attr):
+        domains = []
+        for domain in self.alldomains:
+            if attr in self.alldomains[domain].attributes:
+                domains.append(domain)
+        return domains
+
+    def PrintScontexts(self):
+        for d in sorted(self.alldomains.keys()):
+            sctx = self.alldomains[d]
+            print(d)
+            print("\tcoredomain="+str(sctx.coredomain))
+            print("\tappdomain="+str(sctx.appdomain))
+            print("\tfromSystem="+str(sctx.fromSystem))
+            print("\tfromVendor="+str(sctx.fromVendor))
+            print("\tattributes="+str(sctx.attributes))
+            print("\tentrypoints="+str(sctx.entrypoints))
+            print("\tentrypointpaths=")
+            if sctx.entrypointpaths is not None:
+                for path in sctx.entrypointpaths:
+                    print("\t\t"+str(path))
+
 
 #############################################################
 # Tests
 #############################################################
-def TestCoredomainViolations():
-    global alldomains
+def TestCoredomainViolations(test_policy):
     # verify that all domains launched from /system have the coredomain
     # attribute
     ret = ""
 
-    for d in alldomains:
-        domain = alldomains[d]
+    for d in test_policy.alldomains:
+        domain = test_policy.alldomains[d]
         if domain.fromSystem and domain.fromVendor:
             ret += "The following domain is system and vendor: " + d + "\n"
 
-    for domain in alldomains.values():
+    for domain in test_policy.alldomains.values():
         ret += domain.error
 
     violators = []
-    for d in alldomains:
-        domain = alldomains[d]
+    for d in test_policy.alldomains:
+        domain = test_policy.alldomains[d]
         if domain.fromSystem and "coredomain" not in domain.attributes:
                 violators.append(d);
     if len(violators) > 0:
@@ -228,8 +222,8 @@
     # verify that all domains launched form /vendor do not have the coredomain
     # attribute
     violators = []
-    for d in alldomains:
-        domain = alldomains[d]
+    for d in test_policy.alldomains:
+        domain = test_policy.alldomains[d]
         if domain.fromVendor and "coredomain" in domain.attributes:
             violators.append(d)
     if len(violators) > 0:
@@ -243,17 +237,13 @@
 ###
 # 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
+def TestNoUnmappedNewTypes(test_policy):
+    newt = test_policy.alltypes - test_policy.oldalltypes
     ret = ""
     violators = []
 
     for n in newt:
-        if n in pubtypes and compatMapping.rTypeattributesets.get(n) is None:
+        if n in test_policy.pubtypes and test_policy.compatMapping.rTypeattributesets.get(n) is None:
             violators.append(n)
 
     if len(violators) > 0:
@@ -270,16 +260,13 @@
 ###
 # Make sure that any public type removed in the current policy has its
 # declaration added to the mapping file for use in non-platform policy
-def TestNoUnmappedRmTypes():
-    global alltypes
-    global oldalltypes
-    global compatMapping
-    rmt = oldalltypes - alltypes
+def TestNoUnmappedRmTypes(test_policy):
+    rmt = test_policy.oldalltypes - test_policy.alltypes
     ret = ""
     violators = []
 
     for o in rmt:
-        if o in compatMapping.pubtypes and not o in compatMapping.types:
+        if o in test_policy.compatMapping.pubtypes and not o in test_policy.compatMapping.types:
             violators.append(o)
 
     if len(violators) > 0:
@@ -292,34 +279,32 @@
         ret += "https://android-review.googlesource.com/c/platform/system/sepolicy/+/822743\n"
     return ret
 
-def TestTrebleCompatMapping():
-    ret = TestNoUnmappedNewTypes()
-    ret += TestNoUnmappedRmTypes()
+def TestTrebleCompatMapping(test_policy):
+    ret = TestNoUnmappedNewTypes(test_policy)
+    ret += TestNoUnmappedRmTypes(test_policy)
     return ret
 
-def TestViolatorAttribute(attribute):
-    global FakeTreble
+def TestViolatorAttribute(test_policy, attribute):
     ret = ""
-    if FakeTreble:
+    if test_policy.FakeTreble:
         return ret
 
-    violators = DomainsWithAttribute(attribute)
+    violators = test_policy.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():
+def TestViolatorAttributes(test_policy):
     ret = ""
-    ret += TestViolatorAttribute("socket_between_core_and_vendor_violators")
-    ret += TestViolatorAttribute("vendor_executes_system_violators")
+    ret += TestViolatorAttribute(test_policy, "socket_between_core_and_vendor_violators")
+    ret += TestViolatorAttribute(test_policy, "vendor_executes_system_violators")
     return ret
 
 # TODO move this to sepolicy_tests
-def TestCoreDataTypeViolations():
-    global pol
-    return pol.AssertPathTypesDoNotHaveAttr(["/data/vendor/", "/data/vendor_ce/",
+def TestCoreDataTypeViolations(test_policy):
+    return test_policy.pol.AssertPathTypesDoNotHaveAttr(["/data/vendor/", "/data/vendor_ce/",
         "/data/vendor_de/"], [], "core_data_file_type")
 
 ###
@@ -349,7 +334,7 @@
     Args:
         libpath: string, path to libsepolwrap.so
     """
-    global pol, FakeTreble
+    test_policy = TestPolicy()
 
     usage = "treble_sepolicy_tests "
     usage += "-f nonplat_file_contexts -f plat_file_contexts "
@@ -402,27 +387,27 @@
         oldpol = policy.Policy(options.oldpolicy, None, libpath)
         mapping = mini_parser.MiniCilParser(options.mapping)
         pubpol = mini_parser.MiniCilParser(options.base_pub_policy)
-        compatSetup(basepol, oldpol, mapping, pubpol.types)
+        test_policy.compatSetup(basepol, oldpol, mapping, pubpol.types)
 
     if options.faketreble:
-        FakeTreble = True
+        test_policy.FakeTreble = True
 
     pol = policy.Policy(options.policy, options.file_contexts, libpath)
-    setup(pol)
+    test_policy.setup(pol)
 
     if DEBUG:
-        PrintScontexts()
+        test_policy.PrintScontexts()
 
     results = ""
     # If an individual test is not specified, run all tests.
     if options.tests is None:
         for t in Tests.values():
-            results += t()
+            results += t(test_policy)
     else:
         for tn in options.tests:
             t = Tests.get(tn)
             if t:
-                results += t()
+                results += t(test_policy)
             else:
                 err = "Error: unknown test: " + tn + "\n"
                 err += "Available tests:\n"