Merge "Allow `otapreopt_chroot` to use a flattened Runtime APEX package."
diff --git a/Android.bp b/Android.bp
index eeb6f6c..256262b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12,6 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+cc_defaults { name: "selinux_policy_version", cflags: ["-DSEPOLICY_VERSION=30"], }
+
 se_filegroup {
     name: "26.0.board.compat.map",
     srcs: [
diff --git a/Android.mk b/Android.mk
index bb6cb53..ab88003 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,12 +1,9 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(LOCAL_PATH)/definitions.mk
+include $(LOCAL_PATH)/policy_version.mk
 
 include $(CLEAR_VARS)
-# SELinux policy version.
-# Must be <= /sys/fs/selinux/policyvers reported by the Android kernel.
-# Must be within the compatibility range reported by checkpolicy -V.
-POLICYVERS ?= 30
 
 MLS_SENS=1
 MLS_CATS=1024
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 4ff0f5e..ccb3a50 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,4 @@
 [Hook Scripts]
 whitespace = tools/whitespace.sh ${PREUPLOAD_FILES}
 aosp_hook = ${REPO_ROOT}/frameworks/base/tools/aosp/aosp_sha.sh ${PREUPLOAD_COMMIT} "."
+policy_version_check = tools/policy_version_check.sh
diff --git a/policy_version.mk b/policy_version.mk
new file mode 100644
index 0000000..e6bb747
--- /dev/null
+++ b/policy_version.mk
@@ -0,0 +1,4 @@
+# SELinux policy version.
+# Must be <= /sys/fs/selinux/policyvers reported by the Android kernel.
+# Must be within the compatibility range reported by checkpolicy -V.
+POLICYVERS ?= 30
diff --git a/private/app_zygote.te b/private/app_zygote.te
index e221666..e44c1be 100644
--- a/private/app_zygote.te
+++ b/private/app_zygote.te
@@ -152,6 +152,7 @@
 # neverallow rules for Bluetooth-related data files are listed above.
 neverallow app_zygote {
   bluetooth_a2dp_offload_prop
+  bluetooth_audio_hal_prop
   bluetooth_prop
   exported_bluetooth_prop
 }:file create_file_perms;
diff --git a/private/audioserver.te b/private/audioserver.te
index 1e8b90b..07051af 100644
--- a/private/audioserver.te
+++ b/private/audioserver.te
@@ -42,6 +42,7 @@
 
 # Allow read/write access to bluetooth-specific properties
 set_prop(audioserver, bluetooth_a2dp_offload_prop)
+set_prop(audioserver, bluetooth_audio_hal_prop)
 set_prop(audioserver, bluetooth_prop)
 set_prop(audioserver, exported_bluetooth_prop)
 
diff --git a/private/bluetooth.te b/private/bluetooth.te
index fcbd509..b96fc58 100644
--- a/private/bluetooth.te
+++ b/private/bluetooth.te
@@ -41,6 +41,7 @@
 
 # Allow write access to bluetooth specific properties
 set_prop(bluetooth, bluetooth_a2dp_offload_prop)
+set_prop(bluetooth, bluetooth_audio_hal_prop)
 set_prop(bluetooth, bluetooth_prop)
 set_prop(bluetooth, exported_bluetooth_prop)
 set_prop(bluetooth, pan_result_prop)
diff --git a/private/compat/28.0/28.0.ignore.cil b/private/compat/28.0/28.0.ignore.cil
index 7031977..40a001f 100644
--- a/private/compat/28.0/28.0.ignore.cil
+++ b/private/compat/28.0/28.0.ignore.cil
@@ -25,6 +25,7 @@
     ashmem_device_service
     attention_service
     biometric_service
+    bluetooth_audio_hal_prop
     bpf_progs_loaded_prop
     bugreport_service
     cgroup_desc_file
diff --git a/private/system_app.te b/private/system_app.te
index 38e7938..9a5e455 100644
--- a/private/system_app.te
+++ b/private/system_app.te
@@ -32,6 +32,7 @@
 
 # Write to properties
 set_prop(system_app, bluetooth_a2dp_offload_prop)
+set_prop(system_app, bluetooth_audio_hal_prop)
 set_prop(system_app, bluetooth_prop)
 set_prop(system_app, debug_prop)
 set_prop(system_app, system_prop)
diff --git a/private/system_server_startup.te b/private/system_server_startup.te
index bd7b2c0..ad9fb44 100644
--- a/private/system_server_startup.te
+++ b/private/system_server_startup.te
@@ -7,6 +7,13 @@
 allow system_server_startup self:process execmem;
 allow system_server_startup system_server_startup_tmpfs:file { execute read write open map };
 
+# Allow to pick up integrity-checked artifacts from the dalvik cache.
+allow system_server_startup dalvikcache_data_file:dir r_dir_perms;
+allow system_server_startup dalvikcache_data_file:file { r_file_perms execute };
+
+# While doing the above, will touch the apex mount dir.
+allow system_server_startup mnt_expand_file:dir getattr;
+
 # Allow system_server_startup to run setcon() and enter the
 # system_server domain
 allow system_server_startup self:process setcurrent;
diff --git a/private/webview_zygote.te b/private/webview_zygote.te
index 95affef..4630c35 100644
--- a/private/webview_zygote.te
+++ b/private/webview_zygote.te
@@ -143,6 +143,7 @@
 # neverallow rules for Bluetooth-related data files are listed above.
 neverallow webview_zygote {
   bluetooth_a2dp_offload_prop
+  bluetooth_audio_hal_prop
   bluetooth_prop
   exported_bluetooth_prop
 }:file create_file_perms;
diff --git a/private/zygote.te b/private/zygote.te
index 29d61b4..bfb45f5 100644
--- a/private/zygote.te
+++ b/private/zygote.te
@@ -44,11 +44,10 @@
 allow zygote resourcecache_data_file:dir rw_dir_perms;
 allow zygote resourcecache_data_file:file create_file_perms;
 
-# When WITH_DEXPREOPT is true, the zygote does not load executable content from
-# /data/dalvik-cache. Executable files loaded from /data is a persistence vector
-# we want to avoid. See
-# https://bugs.chromium.org/p/project-zero/issues/detail?id=955 for example.
-allow { zygote with_dexpreopt(`-zygote') } dalvikcache_data_file:file execute;
+# For updateability, the zygote may fetch the current boot
+# classpath from the dalvik cache. Integrity of the files
+# is ensured by fsverity protection (checked in art_apex_boot_integrity).
+allow zygote dalvikcache_data_file:file execute;
 
 # Allow zygote to create JIT memory.
 allow zygote self:process execmem;
@@ -165,6 +164,7 @@
 # Do not allow access to Bluetooth-related system properties and files
 neverallow zygote {
   bluetooth_a2dp_offload_prop
+  bluetooth_audio_hal_prop
   bluetooth_prop
   exported_bluetooth_prop
 }:file create_file_perms;
diff --git a/public/app.te b/public/app.te
index ee9b8cf..e26ec0a 100644
--- a/public/app.te
+++ b/public/app.te
@@ -564,7 +564,7 @@
   appdomain
   -bluetooth
   -system_app
-} { bluetooth_a2dp_offload_prop bluetooth_prop exported_bluetooth_prop }:file create_file_perms;
+} { bluetooth_audio_hal_prop bluetooth_a2dp_offload_prop bluetooth_prop exported_bluetooth_prop }:file create_file_perms;
 
 # Apps cannot access proc_uid_time_in_state
 neverallow appdomain proc_uid_time_in_state:file *;
diff --git a/public/hal_audio.te b/public/hal_audio.te
index 9ffb769..a1c098f 100644
--- a/public/hal_audio.te
+++ b/public/hal_audio.te
@@ -35,3 +35,4 @@
 neverallow { halserverdomain -hal_audio_server } audio_device:chr_file *;
 
 get_prop(hal_audio, bluetooth_a2dp_offload_prop)
+get_prop(hal_audio, bluetooth_audio_hal_prop)
diff --git a/public/hal_bluetooth.te b/public/hal_bluetooth.te
index 09c3ce6..97177ba 100644
--- a/public/hal_bluetooth.te
+++ b/public/hal_bluetooth.te
@@ -21,6 +21,7 @@
 
 # Allow write access to bluetooth-specific properties
 set_prop(hal_bluetooth, bluetooth_a2dp_offload_prop)
+set_prop(hal_bluetooth, bluetooth_audio_hal_prop)
 set_prop(hal_bluetooth, bluetooth_prop)
 set_prop(hal_bluetooth, exported_bluetooth_prop)
 
diff --git a/public/property.te b/public/property.te
index c2b65f0..044e5eb 100644
--- a/public/property.te
+++ b/public/property.te
@@ -2,6 +2,7 @@
 type audio_prop, property_type, core_property_type;
 type boottime_prop, property_type;
 type bluetooth_a2dp_offload_prop, property_type;
+type bluetooth_audio_hal_prop, property_type;
 type bluetooth_prop, property_type;
 type bpf_progs_loaded_prop, property_type;
 type bootloader_boot_reason_prop, property_type;
@@ -351,6 +352,7 @@
     -apexd_prop
     -audio_prop
     -bluetooth_a2dp_offload_prop
+    -bluetooth_audio_hal_prop
     -bluetooth_prop
     -bootloader_boot_reason_prop
     -boottime_prop
diff --git a/public/property_contexts b/public/property_contexts
index 4216116..6845a70 100644
--- a/public/property_contexts
+++ b/public/property_contexts
@@ -12,6 +12,7 @@
 dalvik.vm.appimageformat u:object_r:exported_dalvik_prop:s0 exact string
 dalvik.vm.backgroundgctype u:object_r:exported_dalvik_prop:s0 exact string
 dalvik.vm.boot-dex2oat-threads u:object_r:exported_dalvik_prop:s0 exact int
+dalvik.vm.boot-image u:object_r:exported_dalvik_prop:s0 exact string
 dalvik.vm.checkjni u:object_r:exported_dalvik_prop:s0 exact bool
 dalvik.vm.dex2oat-Xms u:object_r:exported_dalvik_prop:s0 exact string
 dalvik.vm.dex2oat-Xmx u:object_r:exported_dalvik_prop:s0 exact string
@@ -71,6 +72,7 @@
 media.stagefright.thumbnail.prefer_hw_codecs u:object_r:exported3_default_prop:s0 exact bool
 persist.bluetooth.a2dp_offload.cap u:object_r:bluetooth_a2dp_offload_prop:s0 exact string
 persist.bluetooth.a2dp_offload.disabled u:object_r:bluetooth_a2dp_offload_prop:s0 exact bool
+persist.bluetooth.bluetooth_audio_hal.disabled u:object_r:bluetooth_audio_hal_prop:s0 exact bool
 persist.bluetooth.btsnoopenable u:object_r:exported_bluetooth_prop:s0 exact bool
 persist.config.calibration_fac u:object_r:exported3_default_prop:s0 exact string
 persist.dbg.volte_avail_ovr u:object_r:exported3_default_prop:s0 exact int
diff --git a/public/vendor_init.te b/public/vendor_init.te
index fd0d6e3..6ed7b02 100644
--- a/public/vendor_init.te
+++ b/public/vendor_init.te
@@ -213,6 +213,7 @@
 allow vendor_init file_contexts_file:file r_file_perms;
 
 set_prop(vendor_init, bluetooth_a2dp_offload_prop)
+set_prop(vendor_init, bluetooth_audio_hal_prop)
 set_prop(vendor_init, cpu_variant_prop)
 set_prop(vendor_init, debug_prop)
 set_prop(vendor_init, exported_audio_prop)
diff --git a/tools/policy_version_check.sh b/tools/policy_version_check.sh
new file mode 100755
index 0000000..33ce861
--- /dev/null
+++ b/tools/policy_version_check.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+MK=$(awk -F= '/POLICYVERS/ { print $2 }' policy_version.mk | tr -d ' [:space:]')
+BP=$(awk -F= '/DSEPOLICY_VERSION/ { print $2 }' Android.bp | awk -F\" ' { print $1 }')
+
+if [ "$MK" != "$BP" ]; then
+    echo "POLICYVERS in Android.mk must match DSEPOLICY_VERSION in Android.bp" 1>&2
+    exit 1
+fi
diff --git a/tools/sepolicy-analyze/neverallow.c b/tools/sepolicy-analyze/neverallow.c
index 25e6a0c..0209678 100644
--- a/tools/sepolicy-analyze/neverallow.c
+++ b/tools/sepolicy-analyze/neverallow.c
@@ -380,6 +380,7 @@
     size_t keyword_size = strlen(keyword), len;
     struct avrule *neverallows = NULL, *avrule;
     char *p, *start;
+    int result;
 
     p = text;
     while (p < end) {
@@ -434,12 +435,19 @@
     if (!neverallows)
         goto err;
 
-    return check_assertions(NULL, policydb, neverallows);
+    result = check_assertions(NULL, policydb, neverallows);
+    avrule_list_destroy(neverallows);
+    return result;
 err:
     if (errno == ENOMEM) {
         fprintf(stderr, "Out of memory while parsing neverallow rules\n");
     } else
         fprintf(stderr, "Error while parsing neverallow rules\n");
+
+    avrule_list_destroy(neverallows);
+    if (avrule != neverallows)
+        avrule_destroy(avrule);
+
     return -1;
 }