Merge "Revert "Revert "SELinux policy changes for uprobe.""" into main
diff --git a/microdroid/system/private/file.te b/microdroid/system/private/file.te
index c6ed654..62ca9b7 100644
--- a/microdroid/system/private/file.te
+++ b/microdroid/system/private/file.te
@@ -14,10 +14,6 @@
 
 type authfs_fuse, fs_type, contextmount_type;
 
-# /dev/selinux/test - used to verify that apex sepolicy is loaded and
-# property labeled.
-type sepolicy_test_file, file_type;
-
 # /system/bin/mke2fs - used to format encryptedstore block device
 type e2fs_exec, system_file_type, exec_type, file_type;
 
diff --git a/microdroid/system/private/kernel.te b/microdroid/system/private/kernel.te
index e81173d..1d03c4a 100644
--- a/microdroid/system/private/kernel.te
+++ b/microdroid/system/private/kernel.te
@@ -81,16 +81,3 @@
 
 #-----------------------------------------
 allow kernel apkdmverity:fd use;
-
-# Some contexts are changed before the device is flipped into enforcing mode
-# during the setup of Apex sepolicy. These denials can be suppressed since
-# the permissions should not be allowed after the device is flipped into
-# enforcing mode.
-dontaudit kernel device:dir { open read relabelto };
-dontaudit kernel tmpfs:file { getattr open read relabelfrom };
-dontaudit kernel {
-  file_contexts_file
-  property_contexts_file
-  sepolicy_test_file
-  service_contexts_file
-}:file relabelto;
diff --git a/private/apexd.te b/private/apexd.te
index f158ef6..b62e6e6 100644
--- a/private/apexd.te
+++ b/private/apexd.te
@@ -13,14 +13,6 @@
 allow apexd apex_metadata_file:dir create_dir_perms;
 allow apexd apex_metadata_file:file create_file_perms;
 
-# Allow creating and writing APEX files/dirs in the SEPolicy metadata dir
-allow apexd sepolicy_metadata_file:dir create_dir_perms;
-allow apexd sepolicy_metadata_file:file create_file_perms;
-# Allow apexd to setup fs-verity for SEPolicy files in metadata
-allowxperm apexd sepolicy_metadata_file:file ioctl  {
-  FS_IOC_ENABLE_VERITY FS_IOC_MEASURE_VERITY
-};
-
 # Allow reserving space on /data/apex/ota_reserved for apex decompression
 allow apexd apex_ota_reserved_file:dir create_dir_perms;
 allow apexd apex_ota_reserved_file:file create_file_perms;
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.te b/private/file.te
index ee5f047..f4c3e2d 100644
--- a/private/file.te
+++ b/private/file.te
@@ -118,13 +118,6 @@
 # /apex/com.android.compos/bin/compos_key_helper
 type compos_key_helper_exec, exec_type, file_type, system_file_type;
 
-# /metadata/sepolicy
-type sepolicy_metadata_file, file_type;
-
-# /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.
diff --git a/private/file_contexts b/private/file_contexts
index 2b9efc9..1049273 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -205,14 +205,6 @@
 #
 /linkerconfig(/.*)?          u:object_r:linkerconfig_file:s0
 
-# Apex sepoolicy files.
-/dev/selinux/apex_file_contexts                 u:object_r:file_contexts_file:s0
-/dev/selinux/apex_seapp_contexts                u:object_r:seapp_contexts_file:s0
-/dev/selinux/apex_service_contexts              u:object_r:service_contexts_file:s0
-/dev/selinux/apex_property_contexts             u:object_r:property_contexts_file:s0
-/dev/selinux/apex_hwservice_contexts            u:object_r:hwservice_contexts_file:s0
-/dev/selinux/apex_mac_permissions\.xml          u:object_r:mac_perms_file:s0
-
 #############################
 # System files
 #
@@ -844,7 +836,6 @@
 /metadata/password_slots(/.*)?    u:object_r:password_slot_metadata_file:s0
 /metadata/ota(/.*)?       u:object_r:ota_metadata_file:s0
 /metadata/bootstat(/.*)?  u:object_r:metadata_bootstat_file:s0
-/metadata/sepolicy(/.*)?    u:object_r:sepolicy_metadata_file:s0
 /metadata/staged-install(/.*)?    u:object_r:staged_install_file:s0
 /metadata/userspacereboot(/.*)?    u:object_r:userspace_reboot_metadata_file:s0
 /metadata/watchdog(/.*)?    u:object_r:watchdog_metadata_file:s0
diff --git a/private/kernel.te b/private/kernel.te
index 03ba79f..2d46b3e 100644
--- a/private/kernel.te
+++ b/private/kernel.te
@@ -44,19 +44,3 @@
 dontaudit kernel dm_user_device:chr_file { create setattr };
 dontaudit kernel tmpfs:lnk_file read;
 dontaudit kernel tmpfs:blk_file { open read };
-
-# Some contexts are changed before the device is flipped into enforcing mode
-# during the setup of Apex sepolicy. These denials can be suppressed since
-# the permissions should not be allowed after the device is flipped into
-# enforcing mode.
-dontaudit kernel device:dir { open read relabelto };
-dontaudit kernel tmpfs:file { getattr open read relabelfrom };
-dontaudit kernel {
-  file_contexts_file
-  hwservice_contexts_file
-  mac_perms_file
-  property_contexts_file
-  seapp_contexts_file
-  sepolicy_test_file
-  service_contexts_file
-}:file relabelto;
diff --git a/private/ot_daemon.te b/private/ot_daemon.te
index cdf5486..1021fd9 100644
--- a/private/ot_daemon.te
+++ b/private/ot_daemon.te
@@ -20,6 +20,9 @@
 # Allow OT daemon to read/write the Thread tunnel interface
 allow ot_daemon tun_device:chr_file {read write};
 
+# Allow OT daemon to read/write on the socket created by System Server
+allow ot_daemon system_server:rawip_socket rw_socket_perms_no_ioctl;
+
 hal_client_domain(ot_daemon, hal_threadnetwork)
 
 # Only ot_daemon can publish the binder service
diff --git a/private/system_server.te b/private/system_server.te
index 1c3fbbb..5594874 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -1114,7 +1114,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;
diff --git a/public/hal_dumpstate.te b/public/hal_dumpstate.te
index 193b05a..eaa223b 100644
--- a/public/hal_dumpstate.te
+++ b/public/hal_dumpstate.te
@@ -9,6 +9,8 @@
 
 binder_call(hal_dumpstate_server, servicemanager)
 
+binder_use(hal_dumpstate_server)
+
 # write bug reports in /data/data/com.android.shell/files/bugreports/bugreport
 allow hal_dumpstate shell_data_file:file write;
 # allow reading /proc/interrupts for all hal impls
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..9fdc43c 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] + "$")
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)