Merge "tracing: SELinux access to a couple of more binder events" into main
diff --git a/Android.bp b/Android.bp
index 1d06d7d..6c8fa2a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -556,8 +556,8 @@
     properties: ["vendor", "device_specific"],
 }
 
-precompiled_se_policy_binary {
-    name: "precompiled_sepolicy",
+filegroup {
+    name: "precompiled_sepolicy_srcs",
     srcs: [
         ":plat_sepolicy.cil",
         ":plat_pub_versioned.cil",
@@ -569,6 +569,16 @@
         ":system_ext_mapping_file",
         ":product_mapping_file",
     ],
+    // Make precompiled_sepolicy_srcs as public so that OEMs have access to them.
+    // Useful when some partitions need to be bind mounted across VM boundaries.
+    visibility: ["//visibility:public"],
+}
+
+precompiled_se_policy_binary {
+    name: "precompiled_sepolicy",
+    srcs: [
+        ":precompiled_sepolicy_srcs",
+    ],
     soong_config_variables: {
         BOARD_USES_ODMIMAGE: {
             device_specific: true,
diff --git a/apex/Android.bp b/apex/Android.bp
index 45a397a..21054fc 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -281,3 +281,10 @@
     "com.android.devicelock-file_contexts",
   ],
 }
+
+filegroup {
+  name: "com.android.telephonymodules-file_contexts",
+  srcs: [
+    "com.android.telephonymodules-file_contexts"
+  ],
+}
diff --git a/apex/com.android.nfc-file_contexts b/apex/com.android.nfc-file_contexts
new file mode 100644
index 0000000..f6b21da
--- /dev/null
+++ b/apex/com.android.nfc-file_contexts
@@ -0,0 +1,2 @@
+(/.*)?                u:object_r:system_file:s0
+/lib(64)?(/.*)        u:object_r:system_lib_file:s0
diff --git a/apex/com.android.telephonymodules-file_contexts b/apex/com.android.telephonymodules-file_contexts
new file mode 100644
index 0000000..4cee48b
--- /dev/null
+++ b/apex/com.android.telephonymodules-file_contexts
@@ -0,0 +1 @@
+(/.*)?                  u:object_r:system_file:s0
diff --git a/build/soong/service_fuzzer_bindings.go b/build/soong/service_fuzzer_bindings.go
index 9a3396e..44c3243 100644
--- a/build/soong/service_fuzzer_bindings.go
+++ b/build/soong/service_fuzzer_bindings.go
@@ -459,6 +459,7 @@
 		"vibrator":                     EXCEPTION_NO_FUZZER,
 		"vibrator_manager":             EXCEPTION_NO_FUZZER,
 		"virtualdevice":                EXCEPTION_NO_FUZZER,
+		"virtualdevice_native":         EXCEPTION_NO_FUZZER,
 		"virtual_camera_service":       EXCEPTION_NO_FUZZER,
 		"virtual_touchpad":             EXCEPTION_NO_FUZZER,
 		"voiceinteraction":             EXCEPTION_NO_FUZZER,
@@ -467,6 +468,7 @@
 		"vrmanager":                    EXCEPTION_NO_FUZZER,
 		"wallpaper":                    EXCEPTION_NO_FUZZER,
 		"wallpaper_effects_generation": EXCEPTION_NO_FUZZER,
+		"wearable_sensing":             EXCEPTION_NO_FUZZER,
 		"webviewupdate":                EXCEPTION_NO_FUZZER,
 		"wifip2p":                      EXCEPTION_NO_FUZZER,
 		"wifiscanner":                  EXCEPTION_NO_FUZZER,
diff --git a/microdroid/system/private/file_contexts b/microdroid/system/private/file_contexts
index 3498680..e483237 100644
--- a/microdroid/system/private/file_contexts
+++ b/microdroid/system/private/file_contexts
@@ -59,6 +59,7 @@
 /dev/socket/adbd	u:object_r:adbd_socket:s0
 /dev/socket/prng_seeder u:object_r:prng_seeder_socket:s0
 /dev/socket/property_service	u:object_r:property_socket:s0
+/dev/socket/property_service_for_system  u:object_r:property_socket:s0
 /dev/socket/statsdw	u:object_r:statsdw_socket:s0
 /dev/socket/authfs_service u:object_r:authfs_service_socket:s0
 /dev/socket/vm_payload_service u:object_r:vm_payload_service_socket:s0
diff --git a/prebuilts/api/34.0/private/property_contexts b/prebuilts/api/34.0/private/property_contexts
index d38dd4c..2c7557f 100644
--- a/prebuilts/api/34.0/private/property_contexts
+++ b/prebuilts/api/34.0/private/property_contexts
@@ -1326,6 +1326,7 @@
 ro.surface_flinger.display_update_imminent_timeout_ms     u:object_r:surfaceflinger_prop:s0 exact int
 ro.surface_flinger.uclamp.min                             u:object_r:surfaceflinger_prop:s0 exact int
 ro.surface_flinger.ignore_hdr_camera_layers               u:object_r:surfaceflinger_prop:s0 exact bool
+ro.surface_flinger.clear_slots_with_set_layer_buffer      u:object_r:surfaceflinger_prop:s0 exact bool
 
 ro.sf.disable_triple_buffer u:object_r:surfaceflinger_prop:s0 exact bool
 ro.sf.lcd_density           u:object_r:surfaceflinger_prop:s0 exact int
diff --git a/private/app.te b/private/app.te
index 59d9a5f..3c6e5d0 100644
--- a/private/app.te
+++ b/private/app.te
@@ -429,8 +429,8 @@
 allow appdomain shared_relro_file:file r_file_perms;
 
 # Allow apps to read/execute installed binaries
-allow appdomain apk_data_file:dir r_dir_perms;
-allow appdomain apk_data_file:file rx_file_perms;
+allow appdomain apk_data_file:dir { open getattr read search ioctl lock };
+allow appdomain apk_data_file:file { getattr open read ioctl lock map x_file_perms };
 
 # /data/resource-cache
 allow appdomain resourcecache_data_file:file r_file_perms;
@@ -532,3 +532,23 @@
     appdomain
     -device_as_webcam
 } video_device:chr_file { read write };
+
+# Prevent calling inotify on APKs. This can be used as a side channel
+# to observer app launches, so it must be disallowed. b/231587164
+# Gate by targetSdkVersion to avoid breaking existing apps.
+neverallow {
+  appdomain
+  -untrusted_app_25
+  -untrusted_app_27
+  -untrusted_app_29
+  -untrusted_app_30
+  -untrusted_app_32
+} apk_data_file:dir { watch watch_reads };
+neverallow {
+  appdomain
+  -untrusted_app_25
+  -untrusted_app_27
+  -untrusted_app_29
+  -untrusted_app_30
+  -untrusted_app_32
+} apk_data_file:file { watch watch_reads };
diff --git a/private/bug_map b/private/bug_map
index 0a1d741..9aced64 100644
--- a/private/bug_map
+++ b/private/bug_map
@@ -1,6 +1,7 @@
 dnsmasq netd fifo_file b/77868789
 dnsmasq netd unix_stream_socket b/77868789
 gmscore_app system_data_file dir b/146166941
+gmscore_app kernel security b/303319090
 init app_data_file file b/77873135
 init cache_file blk_file b/77873135
 init logpersist file b/77873135
diff --git a/private/compat/34.0/34.0.ignore.cil b/private/compat/34.0/34.0.ignore.cil
index cc240fe..750b78c 100644
--- a/private/compat/34.0/34.0.ignore.cil
+++ b/private/compat/34.0/34.0.ignore.cil
@@ -14,7 +14,9 @@
     virtual_camera_service
     ot_daemon_service
     remote_auth_service
+    sysfs_sync_on_suspend
     threadnetwork_service
     device_config_aconfig_flags_prop
     proc_memhealth
+    virtual_device_native_service
   ))
diff --git a/private/domain.te b/private/domain.te
index 1b8fcf7..1ecb7b6 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -683,6 +683,7 @@
 neverallow {
   domain
   -init
+  -vendor_modprobe
   userdebug_or_eng(`-simpleperf_boot')
   -kernel
   -uprobestats
diff --git a/private/dumpstate.te b/private/dumpstate.te
index b369797..18924ca 100644
--- a/private/dumpstate.te
+++ b/private/dumpstate.te
@@ -56,6 +56,9 @@
   binder_call(dumpstate, profcollectd)
 ')
 
+# Allow dumpstate to talk to automotive_display_service over binder
+binder_call(dumpstate, automotive_display_service)
+
 # Collect metrics on boot time created by init
 get_prop(dumpstate, boottime_prop)
 
diff --git a/private/file_contexts b/private/file_contexts
index 1049273..e928d43 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -155,6 +155,7 @@
 /dev/socket/pdx/system/vr/display/vsync	u:object_r:pdx_display_vsync_endpoint_socket:s0
 /dev/socket/prng_seeder	u:object_r:prng_seeder_socket:s0
 /dev/socket/property_service	u:object_r:property_socket:s0
+/dev/socket/property_service_for_system  u:object_r:property_socket:s0
 /dev/socket/racoon	u:object_r:racoon_socket:s0
 /dev/socket/recovery    u:object_r:recovery_socket:s0
 /dev/socket/rild	u:object_r:rild_socket:s0
diff --git a/private/flags_health_check.te b/private/flags_health_check.te
index 64da97b..b1a333c 100644
--- a/private/flags_health_check.te
+++ b/private/flags_health_check.te
@@ -33,6 +33,7 @@
 set_prop(flags_health_check, device_config_memory_safety_native_prop)
 set_prop(flags_health_check, device_config_remote_key_provisioning_native_prop)
 set_prop(flags_health_check, device_config_camera_native_prop)
+set_prop(flags_health_check, device_config_tethering_u_or_later_native_prop)
 
 # system property device_config_boot_count_prop is used for deciding when to perform server
 # configurable flags related disaster recovery. Mistakenly set up by unrelated components can, at a
diff --git a/private/genfs_contexts b/private/genfs_contexts
index a7aec61..3ec6ab1 100644
--- a/private/genfs_contexts
+++ b/private/genfs_contexts
@@ -157,6 +157,7 @@
 genfscon sysfs /power/autosleep u:object_r:sysfs_power:s0
 genfscon sysfs /power/state u:object_r:sysfs_power:s0
 genfscon sysfs /power/suspend_stats u:object_r:sysfs_suspend_stats:s0
+genfscon sysfs /power/sync_on_suspend u:object_r:sysfs_sync_on_suspend:s0
 genfscon sysfs /power/wakeup_count u:object_r:sysfs_power:s0
 genfscon sysfs /power/wake_lock u:object_r:sysfs_wake_lock:s0
 genfscon sysfs /power/wake_unlock u:object_r:sysfs_wake_lock:s0
diff --git a/private/gmscore_app.te b/private/gmscore_app.te
index 46b90c6..b662f4f 100644
--- a/private/gmscore_app.te
+++ b/private/gmscore_app.te
@@ -46,6 +46,7 @@
 dontaudit gmscore_app exec_type:file r_file_perms;
 dontaudit gmscore_app device:dir r_dir_perms;
 dontaudit gmscore_app fs_bpf:dir r_dir_perms;
+dontaudit gmscore_app kernel:security *;
 dontaudit gmscore_app net_dns_prop:file r_file_perms;
 dontaudit gmscore_app proc:file r_file_perms;
 dontaudit gmscore_app proc_interrupts:file r_file_perms;
diff --git a/private/network_stack.te b/private/network_stack.te
index d9135a1..84c8d4d 100644
--- a/private/network_stack.te
+++ b/private/network_stack.te
@@ -63,6 +63,8 @@
 allow network_stack { fs_bpf_net_private fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared fs_bpf_tethering }:dir search;
 allow network_stack { fs_bpf_net_private fs_bpf_net_shared fs_bpf_netd_readonly fs_bpf_netd_shared fs_bpf_tethering }:file { getattr read write };
 allow network_stack bpfloader:bpf { map_read map_write prog_run };
+# allow Tethering(network_stack process) to read flag value in tethering_u_or_later_native namespace
+get_prop(network_stack, device_config_tethering_u_or_later_native_prop)
 
 # Use XFRM (IPsec) netlink sockets
 allow network_stack self:netlink_xfrm_socket { create_socket_perms_no_ioctl nlmsg_write nlmsg_read };
diff --git a/private/property.te b/private/property.te
index 5f8f044..4f13338 100644
--- a/private/property.te
+++ b/private/property.te
@@ -15,6 +15,7 @@
 system_internal_prop(device_config_configuration_prop)
 system_internal_prop(device_config_connectivity_prop)
 system_internal_prop(device_config_swcodec_native_prop)
+system_internal_prop(device_config_tethering_u_or_later_native_prop)
 system_internal_prop(dmesgd_start_prop)
 system_internal_prop(fastbootd_protocol_prop)
 system_internal_prop(gsid_prop)
diff --git a/private/property_contexts b/private/property_contexts
index 39dd3b5..55a1704 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -115,6 +115,7 @@
 suspend.sleep_time_scale_factor u:object_r:suspend_prop:s0 exact double
 suspend.failed_suspend_backoff_enabled u:object_r:suspend_prop:s0 exact bool
 suspend.short_suspend_backoff_enabled u:object_r:suspend_prop:s0 exact bool
+suspend.disable_sync_on_suspend u:object_r:suspend_prop:s0 exact bool
 
 # Fastbootd protocol control property
 fastbootd.protocol    u:object_r:fastbootd_protocol_prop:s0 exact enum usb tcp
@@ -276,6 +277,7 @@
 persist.device_config.window_manager_native_boot.   u:object_r:device_config_window_manager_native_boot_prop:s0
 persist.device_config.memory_safety_native_boot.    u:object_r:device_config_memory_safety_native_boot_prop:s0
 persist.device_config.memory_safety_native.         u:object_r:device_config_memory_safety_native_prop:s0
+persist.device_config.tethering_u_or_later_native.  u:object_r:device_config_tethering_u_or_later_native_prop:s0
 
 # F2FS smart idle maint prop
 persist.device_config.storage_native_boot.smart_idle_maint_enabled u:object_r:smart_idle_maint_enabled_prop:s0 exact bool
@@ -578,6 +580,7 @@
 bluetooth.profile.pan.panu.enabled                   u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.profile.pbap.client.enabled                u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.profile.pbap.server.enabled                u:object_r:bluetooth_config_prop:s0 exact bool
+bluetooth.profile.pbap.sim.enabled                   u:object_r:bluetooth_config_prop:s0 exact bool
 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
 
@@ -669,6 +672,7 @@
 ro.config.alarm_alert         u:object_r:systemsound_config_prop:s0 exact string
 ro.config.alarm_vol_default   u:object_r:systemsound_config_prop:s0 exact int
 ro.config.alarm_vol_steps     u:object_r:systemsound_config_prop:s0 exact int
+ro.config.assistant_vol_min   u:object_r:systemsound_config_prop:s0 exact int
 ro.config.media_vol_default   u:object_r:systemsound_config_prop:s0 exact int
 ro.config.media_vol_steps     u:object_r:systemsound_config_prop:s0 exact int
 ro.config.notification_sound  u:object_r:systemsound_config_prop:s0 exact string
diff --git a/private/service.te b/private/service.te
index ccb9e17..861afb3 100644
--- a/private/service.te
+++ b/private/service.te
@@ -23,3 +23,4 @@
 type transparency_service,          system_server_service, service_manager_type;
 type vfio_handler_service,          service_manager_type;
 type uce_service,                   service_manager_type;
+type wearable_sensing_service,      system_api_service, system_server_service, service_manager_type;
diff --git a/private/service_contexts b/private/service_contexts
index 746cde1..a1fb06b 100644
--- a/private/service_contexts
+++ b/private/service_contexts
@@ -435,6 +435,7 @@
 vibrator                                  u:object_r:vibrator_service:s0
 vibrator_manager                          u:object_r:vibrator_manager_service:s0
 virtualdevice                             u:object_r:virtual_device_service:s0
+virtualdevice_native                      u:object_r:virtual_device_native_service:s0
 virtual_touchpad                          u:object_r:virtual_touchpad_service:s0
 voiceinteraction                          u:object_r:voiceinteraction_service:s0
 vold                                      u:object_r:vold_service:s0
@@ -442,6 +443,7 @@
 vrmanager                                 u:object_r:vr_manager_service:s0
 wallpaper                                 u:object_r:wallpaper_service:s0
 wallpaper_effects_generation              u:object_r:wallpaper_effects_generation_service:s0
+wearable_sensing                          u:object_r:wearable_sensing_service:s0
 webviewupdate                             u:object_r:webviewupdate_service:s0
 wifip2p                                   u:object_r:wifip2p_service:s0
 wifiscanner                               u:object_r:wifiscanner_service:s0
diff --git a/private/system_server.te b/private/system_server.te
index 1c3fbbb..68a0609 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -770,6 +770,7 @@
 set_prop(system_server, device_config_memory_safety_native_boot_prop)
 set_prop(system_server, device_config_memory_safety_native_prop)
 set_prop(system_server, device_config_remote_key_provisioning_native_prop)
+set_prop(system_server, device_config_tethering_u_or_later_native_prop)
 set_prop(system_server, smart_idle_maint_enabled_prop)
 set_prop(system_server, arm64_memtag_prop)
 
@@ -1114,7 +1115,7 @@
 allow system_server toolbox_exec:file rx_file_perms;
 
 # Allow system process to setup fs-verity
-allowxperm system_server { apk_data_file system_data_file apex_system_server_data_file }:file ioctl FS_IOC_ENABLE_VERITY;
+allowxperm system_server { apk_data_file apk_tmp_file system_data_file apex_system_server_data_file }:file ioctl FS_IOC_ENABLE_VERITY;
 
 # Allow system process to measure fs-verity for apps, including those being installed
 allowxperm system_server { apk_data_file apk_tmp_file }:file ioctl FS_IOC_MEASURE_VERITY;
@@ -1335,6 +1336,7 @@
   device_config_swcodec_native_prop
   device_config_aconfig_flags_prop
   device_config_window_manager_native_boot_prop
+  device_config_tethering_u_or_later_native_prop
 }:property_service set;
 
 # Only allow system_server and init to set tuner_server_ctl_prop
diff --git a/private/system_suspend.te b/private/system_suspend.te
index bef7c6d..683d913 100644
--- a/private/system_suspend.te
+++ b/private/system_suspend.te
@@ -37,6 +37,9 @@
 allow system_suspend sysfs_wake_lock:file rw_file_perms;
 allow system_suspend self:global_capability2_class_set block_suspend;
 
+# Allow init to set /sys/power/sync_on_suspend.
+allow init sysfs_sync_on_suspend:file w_file_perms;
+
 neverallow {
     domain
     -atrace # tracing
diff --git a/private/untrusted_app_25.te b/private/untrusted_app_25.te
index 2c0391f..d59245c 100644
--- a/private/untrusted_app_25.te
+++ b/private/untrusted_app_25.te
@@ -59,3 +59,12 @@
   auditallow untrusted_app_25 mdnsd_socket:sock_file write;
   auditallow untrusted_app_25 mdnsd:unix_stream_socket connectto;
 ')
+
+# Allow calling inotify on APKs for backwards compatibility. This is disallowed
+# for targetSdkVersion>=34 to remove a sidechannel.
+allow untrusted_app_25 apk_data_file:dir { watch watch_reads };
+allow untrusted_app_25 apk_data_file:file { watch watch_reads };
+userdebug_or_eng(`
+  auditallow untrusted_app_25 apk_data_file:dir { watch watch_reads };
+  auditallow untrusted_app_25 apk_data_file:file { watch watch_reads };
+')
diff --git a/private/untrusted_app_27.te b/private/untrusted_app_27.te
index 163803a..8c970d8 100644
--- a/private/untrusted_app_27.te
+++ b/private/untrusted_app_27.te
@@ -47,3 +47,12 @@
   auditallow untrusted_app_27 mdnsd_socket:sock_file write;
   auditallow untrusted_app_27 mdnsd:unix_stream_socket connectto;
 ')
+
+# Allow calling inotify on APKs for backwards compatibility. This is disallowed
+# for targetSdkVersion>=34 to remove a sidechannel.
+allow untrusted_app_27 apk_data_file:dir { watch watch_reads };
+allow untrusted_app_27 apk_data_file:file { watch watch_reads };
+userdebug_or_eng(`
+  auditallow untrusted_app_27 apk_data_file:dir { watch watch_reads };
+  auditallow untrusted_app_27 apk_data_file:file { watch watch_reads };
+')
diff --git a/private/untrusted_app_29.te b/private/untrusted_app_29.te
index 758ed23..ed0bbfc 100644
--- a/private/untrusted_app_29.te
+++ b/private/untrusted_app_29.te
@@ -25,3 +25,12 @@
   auditallow untrusted_app_29 mdnsd_socket:sock_file write;
   auditallow untrusted_app_29 mdnsd:unix_stream_socket connectto;
 ')
+
+# Allow calling inotify on APKs for backwards compatibility. This is disallowed
+# for targetSdkVersion>=34 to remove a sidechannel.
+allow untrusted_app_29 apk_data_file:dir { watch watch_reads };
+allow untrusted_app_29 apk_data_file:file { watch watch_reads };
+userdebug_or_eng(`
+  auditallow untrusted_app_29 apk_data_file:dir { watch watch_reads };
+  auditallow untrusted_app_29 apk_data_file:file { watch watch_reads };
+')
diff --git a/private/untrusted_app_30.te b/private/untrusted_app_30.te
index 830106d..c87548e 100644
--- a/private/untrusted_app_30.te
+++ b/private/untrusted_app_30.te
@@ -27,3 +27,12 @@
   auditallow untrusted_app_30 mdnsd_socket:sock_file write;
   auditallow untrusted_app_30 mdnsd:unix_stream_socket connectto;
 ')
+
+# Allow calling inotify on APKs for backwards compatibility. This is disallowed
+# for targetSdkVersion>=34 to remove a sidechannel.
+allow untrusted_app_30 apk_data_file:dir { watch watch_reads };
+allow untrusted_app_30 apk_data_file:file { watch watch_reads };
+userdebug_or_eng(`
+  auditallow untrusted_app_30 apk_data_file:dir { watch watch_reads };
+  auditallow untrusted_app_30 apk_data_file:file { watch watch_reads };
+')
diff --git a/private/untrusted_app_32.te b/private/untrusted_app_32.te
index 643c122..6e95fd1 100644
--- a/private/untrusted_app_32.te
+++ b/private/untrusted_app_32.te
@@ -28,3 +28,12 @@
   auditallow untrusted_app_32 mdnsd_socket:sock_file write;
   auditallow untrusted_app_32 mdnsd:unix_stream_socket connectto;
 ')
+
+# Allow calling inotify on APKs for backwards compatibility. This is disallowed
+# for targetSdkVersion>=34 to remove a sidechannel.
+allow untrusted_app_32 apk_data_file:dir { watch watch_reads };
+allow untrusted_app_32 apk_data_file:file { watch watch_reads };
+userdebug_or_eng(`
+  auditallow untrusted_app_32 apk_data_file:dir { watch watch_reads };
+  auditallow untrusted_app_32 apk_data_file:file { watch watch_reads };
+')
diff --git a/public/file.te b/public/file.te
index 74aca61..72f511b 100644
--- a/public/file.te
+++ b/public/file.te
@@ -116,6 +116,7 @@
 type sysfs_rtc, fs_type, sysfs_type;
 type sysfs_suspend_stats, fs_type, sysfs_type;
 type sysfs_switch, fs_type, sysfs_type;
+type sysfs_sync_on_suspend, fs_type, sysfs_type;
 type sysfs_transparent_hugepage, fs_type, sysfs_type;
 type sysfs_lru_gen_enabled, fs_type, sysfs_type;
 type sysfs_usb, fs_type, sysfs_type;
diff --git a/public/service.te b/public/service.te
index 8cc5acc..e018e40 100644
--- a/public/service.te
+++ b/public/service.te
@@ -83,7 +83,7 @@
 type binder_calls_stats_service, system_server_service, service_manager_type;
 type blob_store_service, app_api_service, system_server_service, service_manager_type;
 type bluetooth_manager_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
-type broadcastradio_service, system_server_service, service_manager_type;
+type broadcastradio_service, app_api_service, system_server_service, service_manager_type;
 type cacheinfo_service, system_api_service, system_server_service, service_manager_type;
 type cameraproxy_service, system_server_service, service_manager_type;
 type clipboard_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
@@ -256,6 +256,7 @@
 type vibrator_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type vibrator_manager_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type virtual_device_service, app_api_service, system_server_service, service_manager_type;
+type virtual_device_native_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type voiceinteraction_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
 type vpn_management_service, app_api_service, system_server_service, service_manager_type;
 type vr_manager_service, system_server_service, service_manager_type;
diff --git a/public/shell.te b/public/shell.te
index 6c67cea..d4d13e3 100644
--- a/public/shell.te
+++ b/public/shell.te
@@ -63,8 +63,6 @@
 allow shell shell_exec:file rx_file_perms;
 allow shell zygote_exec:file rx_file_perms;
 
-r_dir_file(shell, apk_data_file)
-
 userdebug_or_eng(`
   # "systrace --boot" support - allow boottrace service to run
   allow shell boottrace_data_file:dir rw_dir_perms;
diff --git a/tests/Android.bp b/tests/Android.bp
index 2c2c9a6..743c856 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -159,3 +159,20 @@
         "mini_cil_parser",
     ],
 }
+
+python_test_host {
+    name: "policy_test",
+    srcs: [
+        "fc_sort.py",
+        "policy.py",
+        "policy_test.py",
+    ],
+    test_options: {
+        unit_test: true,
+    },
+    version: {
+        py3: {
+            embedded_launcher: true,
+        },
+    },
+}
diff --git a/tests/policy.py b/tests/policy.py
index 805c451..8fc2ef7 100644
--- a/tests/policy.py
+++ b/tests/policy.py
@@ -30,7 +30,46 @@
 # 1) there is a match - return True or 2) run out of characters - return
 #    False.
 #
+COMMON_PREFIXES = {
+    "/(vendor|system/vendor)": ["/vendor", "/system/vendor"],
+    "/(odm|vendor/odm)": ["/odm", "/vendor/odm"],
+    "/(product|system/product)": ["/product", "/system/product"],
+    "/(system_ext|system/system_ext)": ["/system_ext", "/system/system_ext"],
+}
+
 def MatchPathPrefix(pathregex, prefix):
+    # Before running regex compile loop, try two heuristics, because compiling
+    # regex is too expensive. These two can handle more than 90% out of all
+    # MatchPathPrefix calls.
+
+    # Heuristic 1: handle common prefixes for partitions
+    for c in COMMON_PREFIXES:
+        if not pathregex.startswith(c):
+            continue
+        found = False
+        for p in COMMON_PREFIXES[c]:
+            if prefix.startswith(p):
+                found = True
+                prefix = prefix[len(p):]
+                pathregex = pathregex[len(c):]
+                break
+        if not found:
+            return False
+
+    # Heuristic 2: compare normal characters as long as possible
+    idx = 0
+    while idx < len(prefix):
+        if idx == len(pathregex):
+            return False
+        if pathregex[idx] in fc_sort.META_CHARS or pathregex[idx] == '\\':
+            break
+        if pathregex[idx] != prefix[idx]:
+            return False
+        idx += 1
+    if idx == len(prefix):
+        return True
+
+    # Fall back to regex compile loop.
     for i in range(len(pathregex), 0, -1):
         try:
             pattern = re.compile('^' + pathregex[0:i] + "$")
@@ -70,17 +109,22 @@
         # Query policy for the types associated with Attr
         TypesPol = self.QueryTypeAttribute(Attr, True) - set(ExcludedTypes)
         # Search file_contexts to find types associated with input paths.
-        TypesFc, Files = self.__GetTypesAndFilesByFilePathPrefix(MatchPrefix, DoNotMatchPrefix)
-        violators = TypesFc.intersection(TypesPol)
+        PathTypes = self.__GetTypesAndFilesByFilePathPrefix(MatchPrefix, DoNotMatchPrefix)
+        violators = set()
+        for PathType in PathTypes:
+            filepath, filetype = PathType
+            if filetype in TypesPol:
+                violators.add((str(filetype), str(filepath)))
+
         ret = ""
         if len(violators) > 0:
             ret += "The following types on "
             ret += " ".join(str(x) for x in sorted(MatchPrefix))
             ret += " must not be associated with the "
-            ret += "\"" + Attr + "\" attribute: "
-            ret += " ".join(str(x) for x in sorted(violators)) + "\n"
-            ret += " corresponding to files: "
-            ret += " ".join(str(x) for x in sorted(Files)) + "\n"
+            ret += "\"" + Attr + "\" attribute.\n"
+            ret += "Violator types and corresponding paths:\n"
+            ret += "\n".join(str(x) for x in sorted(violators))
+            ret += "\n"
         return ret
 
     # Check that all types for "filesystem" have "attribute" associated with them
@@ -107,18 +151,22 @@
         TypesPol = self.QueryTypeAttribute(Attr, True)
         # Search file_contexts to find paths/types that should be associated with
         # Attr.
-        TypesFc, Files = self.__GetTypesAndFilesByFilePathPrefix(MatchPrefix, DoNotMatchPrefix)
-        violators = TypesFc.difference(TypesPol)
+        PathTypes = self.__GetTypesAndFilesByFilePathPrefix(MatchPrefix, DoNotMatchPrefix)
+        violators = set()
+        for PathType in PathTypes:
+            filepath, filetype = PathType
+            if filetype not in TypesPol:
+                violators.add((str(filetype), str(filepath)))
 
         ret = ""
         if len(violators) > 0:
             ret += "The following types on "
             ret += " ".join(str(x) for x in sorted(MatchPrefix))
             ret += " must be associated with the "
-            ret += "\"" + Attr + "\" attribute: "
-            ret += " ".join(str(x) for x in sorted(violators)) + "\n"
-            ret += " corresponding to files: "
-            ret += " ".join(str(x) for x in sorted(Files)) + "\n"
+            ret += "\"" + Attr + "\" attribute.\n"
+            ret += "Violator types and corresponding paths:\n"
+            ret += "\n".join(str(x) for x in sorted(violators))
+            ret += "\n"
         return ret
 
     def AssertPropertyOwnersAreExclusive(self):
@@ -295,8 +343,7 @@
     # Return types that match MatchPrefixes but do not match
     # DoNotMatchPrefixes
     def __GetTypesAndFilesByFilePathPrefix(self, MatchPrefixes, DoNotMatchPrefixes):
-        Types = set()
-        Files = set()
+        ret = []
 
         MatchPrefixesWithIndex = []
         for MatchPrefix in MatchPrefixes:
@@ -307,9 +354,8 @@
             for PathType in PathTypes:
                 if MatchPathPrefixes(PathType[0], DoNotMatchPrefixes):
                     continue
-                Types.add(PathType[1])
-                Files.add(PathType[0])
-        return Types, Files
+                ret.append(PathType)
+        return ret
 
     def __GetTERules(self, policydbP, avtabIterP, Rules):
         if Rules is None:
diff --git a/tests/policy_test.py b/tests/policy_test.py
new file mode 100644
index 0000000..3cf4a1b
--- /dev/null
+++ b/tests/policy_test.py
@@ -0,0 +1,56 @@
+# Copyright 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests for policy"""
+
+import unittest
+from policy import MatchPathPrefix
+
+# pylint: disable=missing-docstring
+class PolicyTests(unittest.TestCase):
+    def assertMatches(self, path, prefix):
+        self.assertTrue(MatchPathPrefix(path, prefix))
+
+    def assertDoesNotMatch(self, path, prefix):
+        self.assertFalse(MatchPathPrefix(path, prefix))
+
+    # tests
+
+    def test_match_path_prefix(self):
+        # check common prefix heuristics
+        self.assertMatches("/(vendor|system/vendor)/bin/sh", "/vendor/bin")
+        self.assertMatches("/(vendor|system/vendor)/bin/sh", "/system/vendor/bin"),
+        self.assertMatches("/(odm|vendor/odm)/etc/selinux", "/odm/etc"),
+        self.assertMatches("/(odm|vendor/odm)/etc/selinux", "/vendor/odm/etc"),
+        self.assertMatches("/(system_ext|system/system_ext)/bin/foo", "/system_ext/bin"),
+        self.assertMatches("/(system_ext|system/system_ext)/bin/foo", "/system/system_ext/bin"),
+        self.assertMatches("/(product|system/product)/lib/libc.so", "/product/lib"),
+        self.assertMatches("/(product|system/product)/lib/libc.so", "/system/product/lib"),
+        self.assertDoesNotMatch("/(vendor|system/vendor)/bin/sh", "/system/bin"),
+        self.assertDoesNotMatch("/(odm|vendor/odm)/etc/selinux", "/vendor/etc"),
+        self.assertDoesNotMatch("/(system_ext|system/system_ext)/bin/foo", "/system/bin"),
+        self.assertDoesNotMatch("/(product|system/product)/lib/libc.so", "/system/lib"),
+
+        # check generic regex
+        self.assertMatches("(/.*)+", "/system/etc/vintf")
+        self.assertDoesNotMatch("(/.*)+", "foo/bar/baz")
+
+        self.assertMatches("/(system|product)/lib(64)?(/.*)+.*\.so", "/system/lib/hw/libbaz.so")
+        self.assertMatches("/(system|product)/lib(64)?(/.*)+.*\.so", "/system/lib64/")
+        self.assertMatches("/(system|product)/lib(64)?(/.*)+.*\.so", "/product/lib/hw/libbaz.so")
+        self.assertMatches("/(system|product)/lib(64)?(/.*)+.*\.so", "/product/lib64/")
+        self.assertDoesNotMatch("/(system|product)/lib(64)?(/.*)+.*\.so", "/vendor/lib/hw/libbaz.so")
+        self.assertDoesNotMatch("/(system|product)/lib(64)?(/.*)+.*\.so", "/odm/lib64/")
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)