Merge "Allow dumpstate to make binder calls to mmd" into main
diff --git a/Android.bp b/Android.bp
index 44f064e..15d1596 100644
--- a/Android.bp
+++ b/Android.bp
@@ -335,7 +335,6 @@
     src: ":system_ext_sepolicy.conf",
     system_ext_specific: true,
     filter_out: [":plat_sepolicy.cil"],
-    remove_line_marker: true,
 }
 
 // product_policy.conf - A combination of the private and public product policy
@@ -361,7 +360,6 @@
         ":plat_sepolicy.cil",
         ":system_ext_sepolicy.cil",
     ],
-    remove_line_marker: true,
 }
 
 // policy mapping files
@@ -477,7 +475,7 @@
     src: ":odm_sepolicy.conf",
     filter_out: [
         ":reqd_policy_mask.cil",
-        ":vendor_sepolicy.cil",
+        ":vendor_sepolicy.cil.raw",
     ],
     secilc_check: false, // will be done in se_versioned_policy module
     device_specific: true,
@@ -497,10 +495,7 @@
         ":plat_mapping_file",
         ":vendor_sepolicy.cil",
     ],
-    filter_out: [
-        ":plat_pub_versioned.cil",
-        ":vendor_sepolicy.cil",
-    ],
+    filter_out: [":plat_pub_versioned.cil"],
     device_specific: true,
 }
 
diff --git a/build/Android.bp b/build/Android.bp
index dbe17c8..ef898e8 100644
--- a/build/Android.bp
+++ b/build/Android.bp
@@ -32,3 +32,15 @@
         "version_policy",
     ],
 }
+
+python_test_host {
+    name: "sepolicy_file_utils_test",
+    srcs: [
+        "file_utils.py",
+        "file_utils_test.py",
+    ],
+    main: "file_utils_test.py",
+    test_options: {
+        unit_test: true,
+    },
+}
diff --git a/build/file_utils.py b/build/file_utils.py
index e3210ed..5023fd0 100644
--- a/build/file_utils.py
+++ b/build/file_utils.py
@@ -30,19 +30,72 @@
         os.makedirs(parent_dir)
 
 
+def remove_redundant_line_markers(lines):
+    """
+    Removes any redundant line markers.
+
+    Line markers are to support better error reporting for neverallow rules.
+    Line markers, possibly nested, look like:
+
+        ;;* lm(s|x) LINENO FILENAME
+        (CIL STATEMENTS)
+        ;;* lme
+
+    * lms is used when each of the following CIL statements corresponds to a line
+      in the original file.
+
+    * lmx is used when the following CIL statements are all expanded from a
+      single high-level language line.
+
+    * lme ends a line mark block.
+
+    Redundant line markers are markers without any statements inside. Normally
+    there are no such redundant line markers, but CIL files filtered out by
+    filter_out function below may contain those. remove_redundant_line_markers
+    find all such redundant line markers and removes all of them. See
+    file_utils_test.py for an example.
+    """
+
+    marker_stk = []
+    valid = [False] * len(lines)
+
+    for idx in range(len(lines)):
+        line = lines[idx]
+        if line.startswith(";;* lmx") or line.startswith(";;* lms"):
+            # line start marker
+            marker_stk.append(idx)
+        elif line.startswith(";;* lme"): # line end marker
+            if valid[marker_stk[-1]]:
+                valid[idx] = True
+                # propagate valid to parent markers
+                if len(marker_stk) >= 2:
+                    valid[marker_stk[-2]] = True
+            marker_stk.pop()
+        else:
+            # any other expressions
+            valid[idx] = True
+            # set the current marker as valid
+            if marker_stk:
+                valid[marker_stk[-1]] = True
+
+    return [lines[idx] for idx in range(len(lines)) if valid[idx]]
+
 def filter_out(pattern_files, input_file):
     """"Removes lines in input_file that match any line in pattern_files."""
 
     # Prepares patterns.
     patterns = []
     for f in pattern_files:
-        patterns.extend(open(f).readlines())
+        patterns.extend([x for x in open(f).readlines() if not x.startswith(";;*")])
 
     # Copy lines that are not in the pattern.
     tmp_output = tempfile.NamedTemporaryFile(mode='w+')
     with open(input_file, 'r') as in_file:
-        tmp_output.writelines(line for line in in_file.readlines()
-                              if line not in patterns)
+        lines = [line for line in in_file.readlines()
+                 if line not in patterns and line.strip()]
+        lines = remove_redundant_line_markers(lines)
+        tmp_output.writelines(lines)
+
         # Append empty line because a completely empty file
         # will trip up secilc later on:
         tmp_output.write("\n")
diff --git a/build/file_utils_test.py b/build/file_utils_test.py
new file mode 100644
index 0000000..91ae498
--- /dev/null
+++ b/build/file_utils_test.py
@@ -0,0 +1,59 @@
+# Copyright 2025 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 file_utils"""
+
+import file_utils
+import unittest
+
+
+# pylint: disable=missing-docstring
+class FileUtilsTest(unittest.TestCase):
+
+    # tests
+
+    def test_removing_markers(self):
+        lines = [
+            ";;* lms 1 test_sepolicy.cil",
+            "(type foo)",
+            ";;* lmx 1 foo.te",
+            ";;* lme",
+            ";;* lmx 1 bar.te",
+            ";;* lmx 2 bar.te",
+            ";;* lme",
+            ";;* lme",
+            ";;* lmx 3 bar.te",
+            "(allow foo self (file (read)))",
+            "(neverallow foo self (file (write)))",
+            ";;* lme",
+            ";;* lme", # lms 1 test_sepolicy.cil
+        ]
+
+        expected = [
+            ";;* lms 1 test_sepolicy.cil",
+            "(type foo)",
+            ";;* lmx 3 bar.te",
+            "(allow foo self (file (read)))",
+            "(neverallow foo self (file (write)))",
+            ";;* lme",
+            ";;* lme", # lms 1 test_sepolicy.cil
+        ]
+
+        actual = file_utils.remove_redundant_line_markers(lines)
+
+        # Line markers without any statements must be removed
+        self.assertEqual(actual, expected)
+
+
+if __name__ == '__main__':
+    unittest.main(verbosity=2)
diff --git a/build/soong/policy.go b/build/soong/policy.go
index 8bdf01b..9d71d87 100644
--- a/build/soong/policy.go
+++ b/build/soong/policy.go
@@ -324,9 +324,6 @@
 	// exported policies
 	Filter_out []string `android:"path"`
 
-	// Whether to remove line markers (denoted by ;;) out of compiled cil files. Defaults to false
-	Remove_line_marker *bool
-
 	// Whether to run secilc to check compiled policy or not. Defaults to true
 	Secilc_check *bool
 
@@ -392,17 +389,6 @@
 			Text(">> ").Output(cil)
 	}
 
-	if proptools.Bool(c.properties.Remove_line_marker) {
-		rule.Command().Text("grep -v").
-			Text(proptools.ShellEscape(";;")).
-			Text(cil.String()).
-			Text(">").
-			Text(cil.String() + ".tmp").
-			Text("&& mv").
-			Text(cil.String() + ".tmp").
-			Text(cil.String())
-	}
-
 	if proptools.BoolDefault(c.properties.Secilc_check, true) {
 		secilcCmd := rule.Command().BuiltTool("secilc").
 			Flag("-m").                 // Multiple decls
diff --git a/build/soong/service_fuzzer_bindings.go b/build/soong/service_fuzzer_bindings.go
index a69d649..35b7d7f 100644
--- a/build/soong/service_fuzzer_bindings.go
+++ b/build/soong/service_fuzzer_bindings.go
@@ -524,7 +524,7 @@
 		"wifiaware":                              EXCEPTION_NO_FUZZER,
 		"wifi_usd":                               EXCEPTION_NO_FUZZER,
 		"wifirtt":                                EXCEPTION_NO_FUZZER,
-		"wifi_mainline_supplicant":               EXCEPTION_NO_FUZZER, // defined internally
+		"wifi_mainline_supplicant":               []string{"mainline_supplicant_service_fuzzer"},
 		"window":                                 EXCEPTION_NO_FUZZER,
 		"*":                                      EXCEPTION_NO_FUZZER,
 	}
diff --git a/contexts/plat_file_contexts_test b/contexts/plat_file_contexts_test
index bff3c87..a3e010f 100644
--- a/contexts/plat_file_contexts_test
+++ b/contexts/plat_file_contexts_test
@@ -858,6 +858,7 @@
 /data/system/unsolzygotesocket                                    system_unsolzygote_socket
 /data/drm                                                         drm_data_file
 /data/drm/test                                                    drm_data_file
+/data/system/mediadrm                                             mediadrm_system_data_file
 /data/resource-cache                                              resourcecache_data_file
 /data/resource-cache/test                                         resourcecache_data_file
 /data/dalvik-cache                                                dalvikcache_data_file
diff --git a/flagging/Android.bp b/flagging/Android.bp
index c92991f..b9cef64 100644
--- a/flagging/Android.bp
+++ b/flagging/Android.bp
@@ -31,6 +31,7 @@
         "RELEASE_HARDWARE_BLUETOOTH_RANGING_SERVICE",
         "RELEASE_UNLOCKED_STORAGE_API",
         "RELEASE_BLUETOOTH_SOCKET_SERVICE",
+        "RELEASE_SEPOLICY_RESTRICT_KERNEL_KEYRING_SEARCH",
     ],
     export_to: ["all_selinux_flags"],
 }
diff --git a/microdroid/system/private/microdroid_manager.te b/microdroid/system/private/microdroid_manager.te
index 96a05f7..d2820fb 100644
--- a/microdroid/system/private/microdroid_manager.te
+++ b/microdroid/system/private/microdroid_manager.te
@@ -45,6 +45,11 @@
 allowxperm microdroid_manager vd_device:blk_file ioctl BLKFLSBUF;
 allow microdroid_manager self:global_capability_class_set sys_admin;
 
+# microdroid_manager needs to adjust the priority of the payload process.
+# It requires the sys_nice cap as well.
+allow microdroid_manager microdroid_app:process setsched;
+allow microdroid_manager self:global_capability_class_set sys_nice;
+
 # Allow microdroid_manager to remove capabilities from it's capability bounding set.
 allow microdroid_manager self:global_capability_class_set setpcap;
 
diff --git a/private/app.te b/private/app.te
index b359663..3219fbe 100644
--- a/private/app.te
+++ b/private/app.te
@@ -371,7 +371,7 @@
 
 # Write profiles /data/misc/profiles
 allow appdomain user_profile_root_file:dir search;
-allow appdomain user_profile_data_file:dir w_dir_perms;
+allow appdomain user_profile_data_file:dir rw_dir_perms;
 allow appdomain user_profile_data_file:file create_file_perms;
 
 # Allow writing performance tracing data into the perfetto traced daemon.
@@ -609,6 +609,8 @@
     { create write setattr relabelfrom relabelto append unlink link rename };
 
 # Write to various other parts of /data.
+neverallow appdomain mediadrm_system_data_file:dir_file_class_set
+    { create write setattr relabelfrom relabelto append unlink link rename };
 neverallow appdomain drm_data_file:dir_file_class_set
     { create write setattr relabelfrom relabelto append unlink link rename };
 neverallow { appdomain -platform_app }
diff --git a/private/artd.te b/private/artd.te
index 15d7969..b3f1e5a 100644
--- a/private/artd.te
+++ b/private/artd.te
@@ -37,11 +37,12 @@
 # Read access to primary dex'es on writable partitions
 # ({/data,/mnt/expand/<volume-uuid>}/app/...).
 # Also allow creating the "oat" directory before restorecon.
+# Also allow deleting .sdm files.
 allow artd mnt_expand_file:dir { getattr search };
 allow artd apk_data_file:dir { rw_dir_perms create setattr relabelfrom };
-allow artd apk_data_file:file r_file_perms;
+allow artd apk_data_file:file { r_file_perms unlink };
 allow artd apk_tmp_file:dir { rw_dir_perms create setattr relabelfrom };
-allow artd apk_tmp_file:file r_file_perms;
+allow artd apk_tmp_file:file { r_file_perms unlink };
 
 # Read access to vendor APKs ({/vendor,/odm}/{app,priv-app}/...).
 r_dir_file(artd, vendor_app_file)
diff --git a/private/domain.te b/private/domain.te
index 4282b4d..6999586 100644
--- a/private/domain.te
+++ b/private/domain.te
@@ -530,7 +530,9 @@
 
 # Needed for loading kernel modules.
 # TODO(384942085): Reduce the scope.
+is_flag_disabled(RELEASE_SEPOLICY_RESTRICT_KERNEL_KEYRING_SEARCH, `
 allow domain kernel:key search;
+')
 
 # Allow access to linkerconfig file
 allow domain linkerconfig_file:dir search;
@@ -2318,7 +2320,7 @@
     domain
 
     # these are expected
-    -early_virtmgr
+    is_flag_enabled(RELEASE_AVF_ENABLE_EARLY_VM, `-early_virtmgr')
     -virtualizationmanager
     -virtualizationservice
     -adbd_common # maybe should move to emulator/virtual device specific policy
diff --git a/private/dumpstate.te b/private/dumpstate.te
index 0b717dc..b92ca6f 100644
--- a/private/dumpstate.te
+++ b/private/dumpstate.te
@@ -571,6 +571,9 @@
 allow dumpstate shutdown_checkpoints_system_data_file:dir r_dir_perms;
 allow dumpstate shutdown_checkpoints_system_data_file:file r_file_perms;
 
+# Allow dumpstate to make binder calls to wifi_mainline_supplicant
+binder_call(dumpstate, wifi_mainline_supplicant);
+
 ###
 ### neverallow rules
 ###
diff --git a/private/file.te b/private/file.te
index 6bdcc39..6de346a 100644
--- a/private/file.te
+++ b/private/file.te
@@ -14,6 +14,9 @@
 type fs_bpf_uprobestats, fs_type, bpffs_type;
 type fs_bpf_memevents, fs_type, bpffs_type;
 
+# /data/system/mediadrm
+type mediadrm_system_data_file, file_type, data_file_type, core_data_file_type;
+
 # /data/misc/storaged
 type storaged_data_file, file_type, data_file_type, core_data_file_type;
 
diff --git a/private/file_contexts b/private/file_contexts
index 23a895e..2bed8ed 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -596,6 +596,7 @@
 /data/system/ndebugsocket	u:object_r:system_ndebug_socket:s0
 /data/system/unsolzygotesocket  u:object_r:system_unsolzygote_socket:s0
 /data/drm(/.*)?		u:object_r:drm_data_file:s0
+/data/system/mediadrm(/.*)?		u:object_r:mediadrm_system_data_file:s0
 /data/resource-cache(/.*)? u:object_r:resourcecache_data_file:s0
 /data/dalvik-cache(/.*)? u:object_r:dalvikcache_data_file:s0
 /data/ota(/.*)? u:object_r:ota_data_file:s0
diff --git a/private/hal_widevine_system.te b/private/hal_widevine_system.te
index 57213b3..a9cae31 100644
--- a/private/hal_widevine_system.te
+++ b/private/hal_widevine_system.te
@@ -5,3 +5,10 @@
 init_daemon_domain(hal_widevine_system)
 
 allow hal_widevine_system self:vsock_socket { create_socket_perms_no_ioctl };
+
+get_prop(hal_widevine_system, drm_config_prop)
+get_prop(hal_widevine_system, trusty_widevine_vm_sys_prop)
+
+allow hal_widevine_system mediadrm_system_data_file:dir { create search add_name rw_dir_perms };
+allow hal_widevine_system mediadrm_system_data_file:file { getattr create open read write };
+
diff --git a/private/property_contexts b/private/property_contexts
index 61dcac0..d7c2c94 100644
--- a/private/property_contexts
+++ b/private/property_contexts
@@ -661,6 +661,7 @@
 bluetooth.core.gap.le.conn.min.limit                 u:object_r:bluetooth_config_prop:s0 exact int
 bluetooth.core.gap.le.conn.only_init_1m_phy.enabled  u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.core.le_audio.inband_ringtone.supported    u:object_r:bluetooth_config_prop:s0 exact bool
+bluetooth.core.le_audio.codec_extension_aidl.enabled u:object_r:bluetooth_config_prop:s0 exact bool
 
 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
@@ -729,6 +730,8 @@
 
 bluetooth.core.le.vendor_capabilities.enabled        u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.hfp.software_datapath.enabled              u:object_r:bluetooth_config_prop:s0 exact bool
+bluetooth.hfp.codec_aptx_voice.enabled               u:object_r:bluetooth_config_prop:s0 exact bool
+bluetooth.hfp.swb.aptx.power_management.enabled      u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.sco.disable_enhanced_connection            u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.sco.managed_by_audio                       u:object_r:bluetooth_config_prop:s0 exact bool
 bluetooth.core.le.dsa_transport_preference           u:object_r:bluetooth_config_prop:s0 exact string
diff --git a/private/system_server.te b/private/system_server.te
index 7bdcaef..bdfec3b 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -1296,7 +1296,7 @@
 
 # On userdebug build we may profile system server. Allow it to write and create its own profile.
 userdebug_or_eng(`
-  allow system_server user_profile_data_file:dir w_dir_perms;
+  allow system_server user_profile_data_file:dir rw_dir_perms;
   allow system_server user_profile_data_file:file create_file_perms;
 ')
 # Allow system server to load JVMTI agents under control of a property.
diff --git a/private/vmlauncher_app.te b/private/vmlauncher_app.te
index ef34c31..6c398a2 100644
--- a/private/vmlauncher_app.te
+++ b/private/vmlauncher_app.te
@@ -7,6 +7,9 @@
 allow vmlauncher_app app_api_service:service_manager find;
 allow vmlauncher_app system_api_service:service_manager find;
 
+# TODO(b/402303887): Remove this when WebView doesn't requires camera access.
+allow vmlauncher_app cameraserver_service:service_manager find;
+
 allow vmlauncher_app shell_data_file:dir search;
 allow vmlauncher_app shell_data_file:file { read open write };
 virtualizationservice_use(vmlauncher_app)
diff --git a/private/wifi_mainline_supplicant.te b/private/wifi_mainline_supplicant.te
index c18cef6..dce5a07 100644
--- a/private/wifi_mainline_supplicant.te
+++ b/private/wifi_mainline_supplicant.te
@@ -2,6 +2,7 @@
 type wifi_mainline_supplicant_exec, system_file_type, exec_type, file_type;
 
 binder_use(wifi_mainline_supplicant)
+binder_call(wifi_mainline_supplicant, system_server)
 init_daemon_domain(wifi_mainline_supplicant)
 add_service(wifi_mainline_supplicant, wifi_mainline_supplicant_service)
 
@@ -29,3 +30,7 @@
 allow wifi_mainline_supplicant self:netlink_route_socket { bind create read write nlmsg_readpriv nlmsg_write };
 allow wifi_mainline_supplicant self:netlink_socket create_socket_perms_no_ioctl;
 allow wifi_mainline_supplicant self:netlink_generic_socket create_socket_perms_no_ioctl;
+
+# Dumpstate support
+allow wifi_mainline_supplicant dumpstate:fd use;
+allow wifi_mainline_supplicant dumpstate:fifo_file write;
diff --git a/public/ioctl_defines b/public/ioctl_defines
index 1dd2e3d..df7d1a2 100644
--- a/public/ioctl_defines
+++ b/public/ioctl_defines
@@ -24,6 +24,7 @@
 define(`APEI_ERST_GET_RECORD_COUNT', `0x80044502')
 define(`APM_IOC_STANDBY', `0x00004101')
 define(`APM_IOC_SUSPEND', `0x00004102')
+define(`ASHMEM_GET_FILE_ID', `0x8008770b')
 define(`ASHMEM_GET_NAME', `0x81007702')
 define(`ASHMEM_GET_PIN_STATUS', `0x00007709')
 define(`ASHMEM_GET_PROT_MASK', `0x00007706')
@@ -726,6 +727,9 @@
 define(`F2FS_IOC_SET_COMPRESS_OPTION', `0xf516')
 define(`F2FS_IOC_DECOMPRESS_FILE', `0xf517')
 define(`F2FS_IOC_COMPRESS_FILE', `0xf518')
+define(`F2FS_IOC_START_ATOMIC_REPLACE', `0xf519')
+define(`F2FS_IOC_GET_DEV_ALIAS_FILE', `0xf51a')
+define(`F2FS_IOC_IO_PRIO', `0xf51b')
 define(`F2FS_IOC_SHUTDOWN', `0x587d')
 define(`FAT_IOCTL_GET_ATTRIBUTES', `0x80047210')
 define(`FAT_IOCTL_GET_VOLUME_ID', `0x80047213')
diff --git a/public/ioctl_macros b/public/ioctl_macros
index 64ee1b0..6757acd 100644
--- a/public/ioctl_macros
+++ b/public/ioctl_macros
@@ -75,3 +75,10 @@
 BINDER_SET_CONTEXT_MGR_EXT BINDER_ENABLE_ONEWAY_SPAM_DETECTION
 BINDER_GET_EXTENDED_ERROR
 }')
+
+# ashmem ioctls to be used on memfds for compatibility
+define(`ashmem_ioctls', `{
+ASHMEM_SET_NAME ASHMEM_GET_NAME ASHMEM_SET_SIZE ASHMEM_GET_SIZE
+ASHMEM_SET_PROT_MASK ASHMEM_GET_PROT_MASK ASHMEM_PIN ASHMEM_UNPIN
+ASHMEM_GET_PIN_STATUS ASHMEM_PURGE_ALL_CACHES ASHMEM_GET_FILE_ID
+}')
diff --git a/public/te_macros b/public/te_macros
index 2ba15b3..78e75a0 100644
--- a/public/te_macros
+++ b/public/te_macros
@@ -75,7 +75,8 @@
 # Allow access to a unique type for this domain when creating tmpfs / ashmem files.
 define(`tmpfs_domain', `
 type_transition $1 tmpfs:file $1_tmpfs;
-allow $1 $1_tmpfs:file { read write getattr map };
+allow $1 $1_tmpfs:file { read write getattr map ioctl };
+allowxperm $1 $1_tmpfs:file ioctl ashmem_ioctls;
 ')
 
 # pdx macros for IPC. pdx is a high-level name which contains transport-specific
@@ -243,7 +244,8 @@
 # Label tmpfs objects for all apps.
 type_transition $1 tmpfs:file appdomain_tmpfs;
 userfaultfd_use($1)
-allow $1 appdomain_tmpfs:file { execute getattr map read write };
+allow $1 appdomain_tmpfs:file { execute getattr map read write ioctl };
+allowxperm $1 appdomain_tmpfs:file ioctl ashmem_ioctls;
 neverallow { $1 -runas_app -shell -simpleperf } { domain -$1 }:file no_rw_file_perms;
 neverallow { appdomain -runas_app -shell -simpleperf -$1 } $1:file no_rw_file_perms;
 # The Android security model guarantees the confidentiality and integrity