Merge "remove vendor_service"
diff --git a/apex/com.android.art-file_contexts b/apex/com.android.art-file_contexts
index 2533cac..f1aa92b 100644
--- a/apex/com.android.art-file_contexts
+++ b/apex/com.android.art-file_contexts
@@ -1,10 +1,11 @@
 #############################
 # System files
 #
-(/.*)?                   u:object_r:system_file:s0
-/bin/artd                u:object_r:artd_exec:s0
-/bin/dex2oat(32|64)?     u:object_r:dex2oat_exec:s0
-/bin/dexoptanalyzer      u:object_r:dexoptanalyzer_exec:s0
-/bin/odrefresh           u:object_r:odrefresh_exec:s0
-/bin/profman             u:object_r:profman_exec:s0
-/lib(64)?(/.*)?          u:object_r:system_lib_file:s0
+(/.*)?                         u:object_r:system_file:s0
+/bin/art_exec                  u:object_r:art_exec_exec:s0
+/bin/artd                      u:object_r:artd_exec:s0
+/bin/dex2oat(32|64)?           u:object_r:dex2oat_exec:s0
+/bin/dexoptanalyzer            u:object_r:dexoptanalyzer_exec:s0
+/bin/odrefresh                 u:object_r:odrefresh_exec:s0
+/bin/profman                   u:object_r:profman_exec:s0
+/lib(64)?(/.*)?                u:object_r:system_lib_file:s0
diff --git a/apex/com.android.art.debug-file_contexts b/apex/com.android.art.debug-file_contexts
index a0e9ea0..cc60b70 100644
--- a/apex/com.android.art.debug-file_contexts
+++ b/apex/com.android.art.debug-file_contexts
@@ -2,6 +2,8 @@
 # System files
 #
 (/.*)?                         u:object_r:system_file:s0
+/bin/art_exec                  u:object_r:art_exec_exec:s0
+/bin/artd                      u:object_r:artd_exec:s0
 /bin/dex2oat(d)?(32|64)?       u:object_r:dex2oat_exec:s0
 /bin/dexoptanalyzer(d)?        u:object_r:dexoptanalyzer_exec:s0
 /bin/odrefresh                 u:object_r:odrefresh_exec:s0
diff --git a/microdroid/system/private/domain.te b/microdroid/system/private/domain.te
index 91f7017..4c1baf5 100644
--- a/microdroid/system/private/domain.te
+++ b/microdroid/system/private/domain.te
@@ -48,6 +48,7 @@
 
 # /dev/binder can be accessed by ... everyone! :)
 allow domain binder_device:chr_file rw_file_perms;
+get_prop(domain, servicemanager_prop)
 
 # Restrict binder ioctls to an allowlist. Additional ioctl commands may be
 # added to individual domains, but this sets safe defaults for all processes.
diff --git a/microdroid/system/private/property_contexts b/microdroid/system/private/property_contexts
index 16b40bc..89609b9 100644
--- a/microdroid/system/private/property_contexts
+++ b/microdroid/system/private/property_contexts
@@ -156,6 +156,8 @@
 
 heapprofd.enable u:object_r:heapprofd_prop:s0 exact bool
 
+servicemanager.ready u:object_r:servicemanager_prop:s0 exact bool
+
 # ART properties for CompOS
 dalvik.vm.                                  u:object_r:dalvik_config_prop:s0 prefix
 ro.dalvik.vm.                               u:object_r:dalvik_config_prop:s0 prefix
diff --git a/microdroid/system/private/servicemanager.te b/microdroid/system/private/servicemanager.te
index d51c827..91a8ad2 100644
--- a/microdroid/system/private/servicemanager.te
+++ b/microdroid/system/private/servicemanager.te
@@ -24,6 +24,7 @@
 add_service(servicemanager, service_manager_service)
 
 set_prop(servicemanager, ctl_interface_start_prop)
+set_prop(servicemanager, servicemanager_prop)
 
 # servicemanager is using bootstrap bionic
 use_bootstrap_libs(servicemanager)
diff --git a/microdroid/system/public/property.te b/microdroid/system/public/property.te
index f85ba76..a04fc19 100644
--- a/microdroid/system/public/property.te
+++ b/microdroid/system/public/property.te
@@ -24,6 +24,7 @@
 type ctl_stop_prop, property_type;
 type ctl_tombstone_transmit_prop, property_type;
 type ctl_zipfuse_prop, property_type;
+type servicemanager_prop, property_type;
 type debug_prop, property_type;
 type default_prop, property_type;
 type dev_mnt_prop, property_type;
diff --git a/prebuilts/api/33.0/private/property_contexts b/prebuilts/api/33.0/private/property_contexts
index 1b2360d..2a9ed78 100644
--- a/prebuilts/api/33.0/private/property_contexts
+++ b/prebuilts/api/33.0/private/property_contexts
@@ -728,7 +728,8 @@
 
 # GWP-ASan props. Separate from other libc.debug.* props, because we want users
 # to be able to set them from `adb shell` even on release devices.
-libc.debug.gwp_asan.  u:object_r:gwp_asan_prop:s0 prefix string
+libc.debug.gwp_asan.          u:object_r:gwp_asan_prop:s0 prefix string
+persist.libc.debug.gwp_asan.  u:object_r:gwp_asan_prop:s0 prefix string
 
 # shell-only props for ARM memory tagging (MTE).
 arm64.memtag. u:object_r:arm64_memtag_prop:s0 prefix string
diff --git a/private/access_vectors b/private/access_vectors
index 0f8dd5f..6cd8c4e 100644
--- a/private/access_vectors
+++ b/private/access_vectors
@@ -729,7 +729,6 @@
 	get_state
 	list
 	lock
-	migrate_any_key
 	pull_metrics
 	report_off_body
 	reset
diff --git a/private/artd.te b/private/artd.te
index 4f0db69..dc6855e 100644
--- a/private/artd.te
+++ b/private/artd.te
@@ -1,5 +1,5 @@
-# art service daemon
-type artd, domain, coredomain;
+# ART service daemon.
+typeattribute artd coredomain;
 type artd_exec, system_file_type, exec_type, file_type;
 type artd_tmpfs, file_type;
 
@@ -57,4 +57,23 @@
 #   - managing (CRUD) profile files for both primary dex'es and secondary dex'es
 # - "fowner" is for adjusting the file permissions of compilation artifacts and
 #   profile files based on whether they include user data or not.
-allow artd self:global_capability_class_set { dac_override dac_read_search fowner };
+# - "chown" is for transferring the ownership of compilation artifacts and
+#   profile files to the system or apps.
+allow artd self:global_capability_class_set { dac_override dac_read_search fowner chown };
+
+# Read/write access to profiles (/data/misc/profiles/{ref,cur}/...).
+allow artd user_profile_data_file:dir { getattr search };
+allow artd user_profile_data_file:file create_file_perms;
+
+# Never allow running other binaries without a domain transition.
+# The only exception is art_exec. It is allowed to use the artd domain because
+# it is a thin wrapper that executes other binaries on behalf of artd.
+neverallow artd ~{art_exec_exec}:file execute_no_trans;
+allow artd art_exec_exec:file rx_file_perms;
+
+# Allow running other binaries in their own domains.
+domain_auto_trans(artd, profman_exec, profman)
+domain_auto_trans(artd, dex2oat_exec, dex2oat)
+
+# Allow sending sigkill to subprocesses.
+allow artd { profman dex2oat }:process sigkill;
diff --git a/private/audioserver.te b/private/audioserver.te
index ca29373..7a5e8bc 100644
--- a/private/audioserver.te
+++ b/private/audioserver.te
@@ -43,6 +43,7 @@
 allow audioserver mediametrics_service:service_manager find;
 allow audioserver sensor_privacy_service:service_manager find;
 allow audioserver soundtrigger_middleware_service:service_manager find;
+allow audioserver audio_service:service_manager find;
 
 # Allow read/write access to bluetooth-specific properties
 set_prop(audioserver, bluetooth_a2dp_offload_prop)
diff --git a/private/compat/33.0/33.0.ignore.cil b/private/compat/33.0/33.0.ignore.cil
index 305116c..e943a6d 100644
--- a/private/compat/33.0/33.0.ignore.cil
+++ b/private/compat/33.0/33.0.ignore.cil
@@ -5,10 +5,12 @@
 (typeattribute new_objects)
 (typeattributeset new_objects
   ( new_objects
+    artd
     device_config_memory_safety_native_prop
     device_config_vendor_system_native_prop
     hal_bootctl_service
     permissive_mte_prop
+    servicemanager_prop
     system_net_netd_service
     virtual_face_hal_prop
     virtual_fingerprint_hal_prop
diff --git a/private/coredomain.te b/private/coredomain.te
index 2aa4d0e..9888fa4 100644
--- a/private/coredomain.te
+++ b/private/coredomain.te
@@ -78,6 +78,7 @@
         -heapprofd
         userdebug_or_eng(`-profcollectd')
         -postinstall_dexopt
+        -profman
         -rs # spawned by appdomain, so carryover the exception above
         userdebug_or_eng(`-simpleperf_boot')
         -system_server
diff --git a/private/crash_dump.te b/private/crash_dump.te
index 82ca403..31f0128 100644
--- a/private/crash_dump.te
+++ b/private/crash_dump.te
@@ -20,7 +20,6 @@
   -vold
 }:process { ptrace signal sigchld sigstop sigkill };
 
-# TODO(b/186868271): Remove the keystore exception soon-ish (maybe by May 14, 2021?)
 userdebug_or_eng(`
   allow crash_dump {
     apexd
diff --git a/private/dex2oat.te b/private/dex2oat.te
index e7cdd5f..2ce2459 100644
--- a/private/dex2oat.te
+++ b/private/dex2oat.te
@@ -15,7 +15,6 @@
 
 r_dir_file(dex2oat, dalvikcache_data_file)
 allow dex2oat dalvikcache_data_file:file write;
-allow dex2oat installd:fd use;
 
 # Acquire advisory lock on /system/framework/arm/*
 allow dex2oat system_file:file lock;
@@ -38,12 +37,8 @@
 # Allow dex2oat to find files and directories under /data/misc/apexdata/com.android.runtime.
 allow dex2oat apex_module_data_file:dir search;
 
-# Allow dex2oat to use file descriptors passed from odrefresh.
-allow dex2oat odrefresh:fd use;
-
-# Allow dex2oat to use devpts and file descriptors passed from odsign
+# Allow dex2oat to use devpts passed from odsign.
 allow dex2oat odsign_devpts:chr_file { read write };
-allow dex2oat odsign:fd use;
 
 # Allow dex2oat to write to file descriptors from odrefresh for files
 # in the staging area.
@@ -61,6 +56,9 @@
 # Allow dex2oat to read /apex/apex-info-list.xml
 allow dex2oat apex_info_file:file r_file_perms;
 
+# Allow dex2oat to use file descriptors passed from privileged programs.
+allow dex2oat { artd installd odrefresh odsign }:fd use;
+
 ##################
 # A/B OTA Dexopt #
 ##################
diff --git a/private/file.te b/private/file.te
index c4ee2aa..3f5531f 100644
--- a/private/file.te
+++ b/private/file.te
@@ -115,3 +115,8 @@
 # /dev/selinux/test - used to verify that apex sepolicy is loaded and
 # property labeled.
 type sepolicy_test_file, file_type;
+
+# /apex/com.android.art/bin/art_exec
+# This executable does not have its own domain because it is executed in the caller's domain. For
+# example, it is executed in the `artd` domain when artd calls it.
+type art_exec_exec, system_file_type, exec_type, file_type;
diff --git a/private/profman.te b/private/profman.te
index f61d05e..390f83e 100644
--- a/private/profman.te
+++ b/private/profman.te
@@ -1 +1,12 @@
 typeattribute profman coredomain;
+
+# Allow profman to read APKs and profile files next to them by FDs passed from
+# other programs. In addition, allow profman to acquire flocks on those files.
+allow profman {
+  system_file
+  apk_data_file
+  vendor_app_file
+}:file { getattr read map lock };
+
+# Allow profman to use file descriptors passed from privileged programs.
+allow profman { artd installd }:fd use;
diff --git a/private/property_contexts b/private/property_contexts
index fa794fd..4341bc3 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -220,6 +220,9 @@
 # heapprofd properties
 heapprofd.              u:object_r:heapprofd_prop:s0
 
+# servicemanager properties
+servicemanager.ready    u:object_r:servicemanager_prop:s0 exact bool
+
 # hwservicemanager properties
 hwservicemanager.       u:object_r:hwservicemanager_prop:s0
 
@@ -494,6 +497,7 @@
 bluetooth.framework.adapter_address_validation       u:object_r:bluetooth_config_prop:s0 exact bool
 
 bluetooth.core.gap.le.privacy.enabled                u:object_r:bluetooth_config_prop:s0 exact bool
+bluetooth.core.gap.le.conn.min.limit                 u:object_r:bluetooth_config_prop:s0 exact int
 
 bluetooth.device.default_name                        u:object_r:bluetooth_config_prop:s0 exact string
 bluetooth.device.class_of_device                     u:object_r:bluetooth_config_prop:s0 exact string
@@ -527,6 +531,15 @@
 bluetooth.profile.sap.server.enabled                 u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.profile.vcp.controller.enabled             u:object_r:bluetooth_config_prop:s0 exact bool
 
+bluetooth.core.acl.link_supervision_timeout          u:object_r:bluetooth_config_prop:s0 exact uint
+bluetooth.core.classic.page_scan_type                u:object_r:bluetooth_config_prop:s0 exact uint
+bluetooth.core.classic.page_scan_interval            u:object_r:bluetooth_config_prop:s0 exact uint
+bluetooth.core.classic.page_scan_window              u:object_r:bluetooth_config_prop:s0 exact uint
+bluetooth.core.classic.inq_scan_type                 u:object_r:bluetooth_config_prop:s0 exact uint
+bluetooth.core.classic.inq_scan_interval             u:object_r:bluetooth_config_prop:s0 exact uint
+bluetooth.core.classic.inq_scan_window               u:object_r:bluetooth_config_prop:s0 exact uint
+bluetooth.core.classic.page_timeout                  u:object_r:bluetooth_config_prop:s0 exact uint
+
 persist.nfc.debug_enabled                      u:object_r:nfc_prop:s0 exact bool
 
 persist.radio.multisim.config u:object_r:radio_control_prop:s0 exact string
@@ -1187,6 +1200,7 @@
 ro.surface_flinger.color_space_agnostic_dataspace         u:object_r:surfaceflinger_prop:s0 exact int
 ro.surface_flinger.refresh_rate_switching                 u:object_r:surfaceflinger_prop:s0 exact bool
 ro.surface_flinger.update_device_product_info_on_hotplug_reconnect u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.enable_adpf_cpu_hint                   u:object_r:surfaceflinger_prop:s0 exact bool
 ro.surface_flinger.enable_frame_rate_override             u:object_r:surfaceflinger_prop:s0 exact bool
 ro.surface_flinger.enable_layer_caching                   u:object_r:surfaceflinger_prop:s0 exact bool
 ro.surface_flinger.display_update_imminent_timeout_ms     u:object_r:surfaceflinger_prop:s0 exact int
diff --git a/private/servicemanager.te b/private/servicemanager.te
index 56a41e1..95a9496 100644
--- a/private/servicemanager.te
+++ b/private/servicemanager.te
@@ -5,6 +5,7 @@
 read_runtime_log_tags(servicemanager)
 
 set_prop(servicemanager, ctl_interface_start_prop)
+set_prop(servicemanager, servicemanager_prop)
 
 # servicemanager is using bootstrap bionic
 use_bootstrap_libs(servicemanager)
diff --git a/private/system_server.te b/private/system_server.te
index aac29f6..9ccd22d 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -959,9 +959,7 @@
 	clear_ns
 	clear_uid
 	get_state
-	list
 	lock
-	migrate_any_key
 	pull_metrics
 	reset
 	unlock
diff --git a/public/artd.te b/public/artd.te
new file mode 100644
index 0000000..0731adc
--- /dev/null
+++ b/public/artd.te
@@ -0,0 +1,2 @@
+# ART service daemon.
+type artd, domain;
diff --git a/public/domain.te b/public/domain.te
index 2aa4381..6ef4566 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -80,6 +80,7 @@
 
 # /dev/binder can be accessed by ... everyone! :)
 allow { domain -hwservicemanager -vndservicemanager } binder_device:chr_file rw_file_perms;
+get_prop({domain -hwservicemanager -vndservicemanager }, servicemanager_prop)
 
 # Restrict binder ioctls to an allowlist. Additional ioctl commands may be
 # added to individual domains, but this sets safe defaults for all processes.
@@ -653,6 +654,8 @@
     -app_api_service
     -ephemeral_app_api_service
 
+    -hal_service_type # see app_neverallows.te
+
     -apc_service
     -audioserver_service # TODO(b/36783122) remove exemptions below once app_api_service is fixed
     -cameraserver_service
@@ -1213,11 +1216,12 @@
 neverallow { domain -vold -init -vendor_init } fusectlfs:file no_rw_file_perms;
 
 # Profiles contain untrusted data and profman parses that. We should only run
-# in from installd forked processes.
+# it from installd and artd forked processes.
 neverallow {
   domain
   -installd
   -profman
+  -artd
 } profman_exec:file no_x_file_perms;
 
 # Enforce restrictions on kernel module origin.
diff --git a/public/dumpstate.te b/public/dumpstate.te
index 84c12d9..a2d2417 100644
--- a/public/dumpstate.te
+++ b/public/dumpstate.te
@@ -147,22 +147,28 @@
 binder_call(dumpstate, { appdomain netd wificond })
 
 # Allow dumpstate to call dump() on specific hals.
+dump_hal(hal_authsecret)
+dump_hal(hal_contexthub)
+dump_hal(hal_drm)
 dump_hal(hal_dumpstate)
-dump_hal(hal_wifi)
-dump_hal(hal_graphics_allocator)
-dump_hal(hal_input_processor)
-dump_hal(hal_light)
-dump_hal(hal_neuralnetworks)
-dump_hal(hal_nfc)
-dump_hal(hal_thermal)
-dump_hal(hal_power)
-dump_hal(hal_power_stats)
-dump_hal(hal_identity)
 dump_hal(hal_face)
 dump_hal(hal_fingerprint)
 dump_hal(hal_gnss)
-dump_hal(hal_contexthub)
-dump_hal(hal_drm)
+dump_hal(hal_graphics_allocator)
+dump_hal(hal_identity)
+dump_hal(hal_input_processor)
+dump_hal(hal_keymint)
+dump_hal(hal_light)
+dump_hal(hal_memtrack)
+dump_hal(hal_neuralnetworks)
+dump_hal(hal_nfc)
+dump_hal(hal_oemlock)
+dump_hal(hal_power)
+dump_hal(hal_power_stats)
+dump_hal(hal_rebootescrow)
+dump_hal(hal_thermal)
+dump_hal(hal_weaver)
+dump_hal(hal_wifi)
 
 # Vibrate the device after we are done collecting the bugreport
 hal_client_domain(dumpstate, hal_vibrator)
@@ -348,31 +354,6 @@
 # Allow dumpstate to talk to mediaswcodec over binder
 binder_call(dumpstate, mediaswcodec);
 
-# Allow dumpstate to talk to these stable AIDL services over binder
-binder_call(dumpstate, hal_rebootescrow_server)
-allow hal_rebootescrow_server dumpstate:fifo_file write;
-allow hal_rebootescrow_server dumpstate:fd use;
-
-binder_call(dumpstate, hal_authsecret_server)
-allow hal_authsecret_server dumpstate:fifo_file write;
-allow hal_authsecret_server dumpstate:fd use;
-
-binder_call(dumpstate, hal_keymint_server)
-allow hal_keymint_server dumpstate:fifo_file write;
-allow hal_keymint_server dumpstate:fd use;
-
-binder_call(dumpstate, hal_memtrack_server)
-allow hal_memtrack_server dumpstate:fifo_file write;
-allow hal_memtrack_server dumpstate:fd use;
-
-binder_call(dumpstate, hal_oemlock_server)
-allow hal_oemlock_server dumpstate:fifo_file write;
-allow hal_oemlock_server dumpstate:fd use;
-
-binder_call(dumpstate, hal_weaver_server)
-allow hal_weaver_server dumpstate:fifo_file write;
-allow hal_weaver_server dumpstate:fd use;
-
 #Access /data/misc/snapshotctl_log
 allow dumpstate snapshotctl_log_data_file:dir r_dir_perms;
 allow dumpstate snapshotctl_log_data_file:file r_file_perms;
diff --git a/public/kernel.te b/public/kernel.te
index 09d2480..b01c07a 100644
--- a/public/kernel.te
+++ b/public/kernel.te
@@ -95,10 +95,10 @@
   staging_data_file
   vendor_apex_file
 }:file read;
-# Also allow the kernel to read /data/local/tmp files via loop device
-# for ApexTestCases
+# Also allow the kernel to read/write /data/local/tmp files via loop device
+# for ApexTestCases and fiemap_image_test.
 userdebug_or_eng(`
-  allow kernel shell_data_file:file read;
+  allow kernel shell_data_file:file { read write };
 ')
 
 # Allow the first-stage init (which is running in the kernel domain) to execute the
diff --git a/public/profman.te b/public/profman.te
index c014d79..727daee 100644
--- a/public/profman.te
+++ b/public/profman.te
@@ -14,8 +14,6 @@
 allow profman tmpfs:file { read map };
 allow profman profman_dump_data_file:file { write map };
 
-allow profman installd:fd use;
-
 # Allow profman to analyze profiles for the secondary dex files. These
 # are application dex files reported back to the framework when using
 # BaseDexClassLoader.
diff --git a/public/property.te b/public/property.te
index 9b538cf..865acc2 100644
--- a/public/property.te
+++ b/public/property.te
@@ -82,6 +82,7 @@
 system_restricted_prop(provisioned_prop)
 system_restricted_prop(restorecon_prop)
 system_restricted_prop(retaildemo_prop)
+system_restricted_prop(servicemanager_prop)
 system_restricted_prop(smart_idle_maint_enabled_prop)
 system_restricted_prop(socket_hook_prop)
 system_restricted_prop(sqlite_log_prop)
diff --git a/public/te_macros b/public/te_macros
index 58d04b4..4dd510a 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -758,7 +758,6 @@
         -$1_server
         # some services are allowed to find all services
         -atrace
-        -dumpstate
         -shell
         -system_app
         -traceur_app
diff --git a/public/update_engine_common.te b/public/update_engine_common.te
index e8fd29e..12961e7 100644
--- a/public/update_engine_common.te
+++ b/public/update_engine_common.te
@@ -72,6 +72,7 @@
 # read /dev/dm-user, so that we can inotify wait for control devices to be
 # asynchronously created by ueventd.
 allow update_engine dm_user_device:dir r_dir_perms;
+allow update_engine dm_user_device:chr_file r_file_perms;
 
 # read / write metadata on super device to resize partitions
 allow update_engine_common super_block_device_type:blk_file rw_file_perms;
diff --git a/tests/Android.bp b/tests/Android.bp
index 8ca952d..e271346 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -43,6 +43,11 @@
     srcs: [
         "treble_sepolicy_tests.py",
     ],
+    version: {
+        py3: {
+            embedded_launcher: true,
+        },
+    },
     libs: [
         "mini_cil_parser",
         "pysepolwrap",
@@ -55,6 +60,11 @@
     srcs: [
         "sepolicy_tests.py",
     ],
+    version: {
+        py3: {
+            embedded_launcher: true,
+        },
+    },
     libs: ["pysepolwrap"],
     data: [":libsepolwrap"],
 }
diff --git a/tests/searchpolicy.py b/tests/searchpolicy.py
index 9d2c636..79efecf 100644
--- a/tests/searchpolicy.py
+++ b/tests/searchpolicy.py
@@ -78,10 +78,10 @@
 for r in TERules:
     if len(r.perms) > 1:
         rules.append("allow " + r.sctx + " " + r.tctx + ":" + r.tclass + " { " +
-                " ".join(r.perms) + " };")
+                " ".join(sorted(r.perms)) + " };")
     else:
         rules.append("allow " + r.sctx + " " + r.tctx + ":" + r.tclass + " " +
-                " ".join(r.perms) + ";")
+                " ".join(sorted(r.perms)) + ";")
 
 for r in sorted(rules):
     print(r)
diff --git a/tests/sepolicy_tests.py b/tests/sepolicy_tests.py
index 79c55de..63144dd 100644
--- a/tests/sepolicy_tests.py
+++ b/tests/sepolicy_tests.py
@@ -15,10 +15,14 @@
 from optparse import OptionParser
 from optparse import Option, OptionValueError
 import os
+import pkgutil
 import policy
 import re
+import shutil
 import sys
-import distutils.ccompiler
+import tempfile
+
+SHARED_LIB_EXTENSION = '.dylib' if sys.platform == 'darwin' else '.so'
 
 #############################################################
 # Tests
@@ -145,7 +149,11 @@
     "TestDmaHeapDevTypeViolations",
 ]
 
-if __name__ == '__main__':
+def do_main(libpath):
+    """
+    Args:
+        libpath: string, path to libsepolwrap.so
+    """
     usage = "sepolicy_tests -f vendor_file_contexts -f "
     usage +="plat_file_contexts -p policy [--test test] [--help]"
     parser = OptionParser(option_class=MultipleOption, usage=usage)
@@ -157,11 +165,6 @@
 
     (options, args) = parser.parse_args()
 
-    libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
-        "libsepolwrap" + distutils.ccompiler.new_compiler().shared_lib_extension)
-    if not os.path.exists(libpath):
-        sys.exit("Error: libsepolwrap does not exist. Is this binary corrupted?\n")
-
     if not options.policy:
         sys.exit("Must specify monolithic policy file\n" + parser.usage)
     if not os.path.exists(options.policy):
@@ -206,3 +209,17 @@
 
     if len(results) > 0:
         sys.exit(results)
+
+if __name__ == '__main__':
+    temp_dir = tempfile.mkdtemp()
+    try:
+        libname = "libsepolwrap" + SHARED_LIB_EXTENSION
+        libpath = os.path.join(temp_dir, libname)
+        with open(libpath, "wb") as f:
+            blob = pkgutil.get_data("sepolicy_tests", libname)
+            if not blob:
+                sys.exit("Error: libsepolwrap does not exist. Is this binary corrupted?\n")
+            f.write(blob)
+        do_main(libpath)
+    finally:
+        shutil.rmtree(temp_dir)
diff --git a/tests/treble_sepolicy_tests.py b/tests/treble_sepolicy_tests.py
index a3bf661..b49f138 100644
--- a/tests/treble_sepolicy_tests.py
+++ b/tests/treble_sepolicy_tests.py
@@ -16,13 +16,16 @@
 from optparse import Option, OptionValueError
 import os
 import mini_parser
+import pkgutil
 import policy
 from policy import MatchPathPrefix
 import re
+import shutil
 import sys
-import distutils.ccompiler
+import tempfile
 
 DEBUG=False
+SHARED_LIB_EXTENSION = '.dylib' if sys.platform == 'darwin' else '.so'
 
 '''
 Use file_contexts and policy to verify Treble requirements
@@ -341,7 +344,13 @@
          "TrebleCompatMapping": TestTrebleCompatMapping,
          "ViolatorAttributes": TestViolatorAttributes}
 
-if __name__ == '__main__':
+def do_main(libpath):
+    """
+    Args:
+        libpath: string, path to libsepolwrap.so
+    """
+    global pol, FakeTreble
+
     usage = "treble_sepolicy_tests "
     usage += "-f nonplat_file_contexts -f plat_file_contexts "
     usage += "-p curr_policy -b base_policy -o old_policy "
@@ -374,11 +383,6 @@
             sys.exit("Error: File_contexts file " + f + " does not exist\n" +
                     parser.usage)
 
-    libpath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
-        "libsepolwrap" + distutils.ccompiler.new_compiler().shared_lib_extension)
-    if not os.path.exists(libpath):
-        sys.exit("Error: libsepolwrap does not exist. Is this binary corrupted?\n")
-
     # Mapping files and public platform policy are only necessary for the
     # TrebleCompatMapping test.
     if options.tests is None or options.tests == "TrebleCompatMapping":
@@ -428,3 +432,17 @@
 
     if len(results) > 0:
         sys.exit(results)
+
+if __name__ == '__main__':
+    temp_dir = tempfile.mkdtemp()
+    try:
+        libname = "libsepolwrap" + SHARED_LIB_EXTENSION
+        libpath = os.path.join(temp_dir, libname)
+        with open(libpath, "wb") as f:
+            blob = pkgutil.get_data("treble_sepolicy_tests", libname)
+            if not blob:
+                sys.exit("Error: libsepolwrap does not exist. Is this binary corrupted?\n")
+            f.write(blob)
+        do_main(libpath)
+    finally:
+        shutil.rmtree(temp_dir)
diff --git a/tools/seamendc.c b/tools/seamendc.c
index 1328afb..cd79c76 100644
--- a/tools/seamendc.c
+++ b/tools/seamendc.c
@@ -9,6 +9,7 @@
 #include <cil/cil.h>
 #include <cil/android.h>
 #include <sepol/policydb.h>
+#include "sepol/handle.h"
 
 void usage(const char *prog)
 {
@@ -26,10 +27,17 @@
 
 /*
  * Read binary policy file from path into the allocated pdb.
+ *
+ * We first read the binary policy into memory, and then we parse it to a
+ * policydb object using sepol_policydb_from_image. This combination is slightly
+ * faster than using sepol_policydb_read that reads the binary file in small
+ * chunks at a time.
  */
 static int read_binary_policy(char *path, sepol_policydb_t *pdb)
 {
     int rc = SEPOL_OK;
+    char *buff = NULL;
+    sepol_handle_t *handle = NULL;
 
     FILE *file = fopen(path, "r");
     if (!file) {
@@ -44,24 +52,38 @@
         fprintf(stderr, "Could not stat %s: %s.\n", path, strerror(errno));
         goto exit;
     }
-    if (!binarydata.st_size) {
+
+    uint32_t file_size = binarydata.st_size;
+    if (!file_size) {
         fprintf(stderr, "Binary policy file is empty.\n");
         rc = SEPOL_ERR;
         goto exit;
     }
 
-    struct sepol_policy_file *pf = NULL;
-    rc = sepol_policy_file_create(&pf);
-    if (rc != 0) {
-        fprintf(stderr, "Failed to create policy file: %d.\n", rc);
+    buff = malloc(file_size);
+    if (buff == NULL) {
+        perror("malloc failed");
+        rc = SEPOL_ERR;
         goto exit;
     }
-    sepol_policy_file_set_fp(pf, file);
 
-    rc = sepol_policydb_read(pdb, pf);
+    rc = fread(buff, file_size, 1, file);
+    if (rc != 1) {
+        fprintf(stderr, "Failure reading %s: %s.\n", path, strerror(errno));
+        rc = SEPOL_ERR;
+        goto exit;
+    }
+
+    handle = sepol_handle_create();
+    if (!handle) {
+        perror("Could not create policy handle");
+        rc = SEPOL_ERR;
+        goto exit;
+    }
+
+    rc = sepol_policydb_from_image(handle, buff, file_size, pdb);
     if (rc != 0) {
         fprintf(stderr, "Failed to read binary policy: %d.\n", rc);
-        goto exit;
     }
 
 exit:
@@ -69,6 +91,10 @@
         perror("Failure closing binary file");
         rc = SEPOL_ERR;
     }
+    if(handle != NULL) {
+        sepol_handle_destroy(handle);
+    }
+    free(buff);
     return rc;
 }
 
@@ -123,6 +149,7 @@
             goto parse_err;
         }
         free(buff);
+        buff = NULL;
     }
 
     return SEPOL_OK;