Split user_profile_data_file label.

user_profile_data_file is mlstrustedobject. And it needs to be,
because we want untrusted apps to be able to write to their profile
files, but they do not have levels.

But now we want to apply levels in the parent directories that have
the same label, and we want them to work so they need to not be
MLS-exempt. To resolve that we introduce a new label,
user_profile_root_file, which is applied to those directories (but no
files). We grant mostly the same access to the new label as
directories with the existing label.

Apart from appdomain, almost every domain which accesses
user_profile_data_file, and now user_profile_root_file, is already
mlstrustedsubject and so can't be affected by this change. The
exception is postinstall_dexopt which we now make mlstrustedobject.

Bug: 141677108
Bug: 175311045
Test: Manual: flash with wipe
Test: Manual: flash on top of older version
Test: Manual: install & uninstall apps
Test: Manual: create & remove user
Test: Presubmits.
Change-Id: I4e0def3d513b129d6c292f7edb076db341b4a2b3
diff --git a/private/compat/30.0/30.0.cil b/private/compat/30.0/30.0.cil
index 49a5a77..6c95364 100644
--- a/private/compat/30.0/30.0.cil
+++ b/private/compat/30.0/30.0.cil
@@ -2155,7 +2155,10 @@
 (typeattributeset usbd_exec_30_0 (usbd_exec))
 (typeattributeset usbfs_30_0 (usbfs))
 (typeattributeset use_memfd_prop_30_0 (use_memfd_prop))
-(typeattributeset user_profile_data_file_30_0 (user_profile_data_file))
+(typeattributeset user_profile_data_file_30_0
+  ( user_profile_data_file
+    user_profile_root_file
+))
 (typeattributeset user_service_30_0 (user_service))
 (typeattributeset userdata_block_device_30_0 (userdata_block_device))
 (typeattributeset usermodehelper_30_0 (usermodehelper))
diff --git a/private/file_contexts b/private/file_contexts
index 633a6ce..d2e0b62 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -609,7 +609,8 @@
 /data/misc/wmtrace(/.*)?        u:object_r:wm_trace_data_file:s0
 # TODO(calin) label profile reference differently so that only
 # profman run as a special user can write to them
-/data/misc/profiles/cur(/.*)?       u:object_r:user_profile_data_file:s0
+/data/misc/profiles/cur(/[0-9]+)?   u:object_r:user_profile_root_file:s0
+/data/misc/profiles/cur/[0-9]+/.*   u:object_r:user_profile_data_file:s0
 /data/misc/profiles/ref(/.*)?       u:object_r:user_profile_data_file:s0
 /data/misc/profman(/.*)?        u:object_r:profman_dump_data_file:s0
 /data/vendor(/.*)?              u:object_r:vendor_data_file:s0
diff --git a/private/mls b/private/mls
index 68d0e58..1588a13 100644
--- a/private/mls
+++ b/private/mls
@@ -75,7 +75,7 @@
 # or the object is trusted.
 mlsconstrain dir { read getattr search }
 	     (t2 == app_data_file_type or l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject
-	     or (t1 == mlsvendorcompat and (t2 == system_data_file or t2 == user_profile_data_file) ) );
+	     or (t1 == mlsvendorcompat and (t2 == system_data_file or t2 == user_profile_root_file) ) );
 
 mlsconstrain { file lnk_file sock_file chr_file blk_file } { read getattr execute }
 	     (t2 == app_data_file_type or t2 == appdomain_tmpfs or l1 dom l2 or t1 == mlstrustedsubject or t2 == mlstrustedobject);
diff --git a/private/postinstall_dexopt.te b/private/postinstall_dexopt.te
index fd370c2..4c4960c 100644
--- a/private/postinstall_dexopt.te
+++ b/private/postinstall_dexopt.te
@@ -3,7 +3,7 @@
 # Note: otapreopt is a driver for dex2oat, and reuses parts of installd. As such,
 # this is derived and adapted from installd.te.
 
-type postinstall_dexopt, domain, coredomain;
+type postinstall_dexopt, domain, coredomain, mlstrustedsubject;
 
 # Run dex2oat/patchoat in its own sandbox.
 # We have to manually transition, as we don't have an entrypoint.
@@ -38,7 +38,7 @@
 r_dir_file(postinstall_dexopt, dalvikcache_data_file)
 
 # Read profile data.
-allow postinstall_dexopt user_profile_data_file:dir { getattr search };
+allow postinstall_dexopt { user_profile_root_file user_profile_data_file }:dir { getattr search };
 allow postinstall_dexopt user_profile_data_file:file r_file_perms;
 # Suppress deletion denial (we do not want to update the profile).
 dontaudit postinstall_dexopt user_profile_data_file:file { write };
diff --git a/private/system_server.te b/private/system_server.te
index 90061c6..9979fd5 100644
--- a/private/system_server.te
+++ b/private/system_server.te
@@ -977,7 +977,7 @@
 # Allow system_server to open profile snapshots for read.
 # System server never reads the actual content. It passes the descriptor to
 # to privileged apps which acquire the permissions to inspect the profiles.
-allow system_server user_profile_data_file:dir { getattr search };
+allow system_server { user_profile_root_file user_profile_data_file}:dir { getattr search };
 allow system_server user_profile_data_file:file { getattr open read };
 
 # System server may dump profile data for debuggable apps in the /data/misc/profman.
diff --git a/private/traced_probes.te b/private/traced_probes.te
index c669eba..9da4d94 100644
--- a/private/traced_probes.te
+++ b/private/traced_probes.te
@@ -58,7 +58,7 @@
 allow traced_probes bootstat_data_file:dir { getattr open read search };
 allow traced_probes update_engine_data_file:dir { getattr open read search };
 allow traced_probes update_engine_log_data_file:dir { getattr open read search };
-allow traced_probes user_profile_data_file:dir { getattr open read search };
+allow traced_probes { user_profile_root_file user_profile_data_file}:dir { getattr open read search };
 
 # Allow traced_probes to run atrace. atrace pokes at system services to enable
 # their userspace TRACE macros.
@@ -113,6 +113,7 @@
   -bootstat_data_file
   -update_engine_data_file
   -update_engine_log_data_file
+  -user_profile_root_file
   -user_profile_data_file
   # TODO(b/72998741) Remove vendor_data_file exemption. Further restricted in a
   # subsequent neverallow. Currently only getattr and search are allowed.
diff --git a/private/vold_prepare_subdirs.te b/private/vold_prepare_subdirs.te
index 4197ddd..9bea43c 100644
--- a/private/vold_prepare_subdirs.te
+++ b/private/vold_prepare_subdirs.te
@@ -45,7 +45,8 @@
 }:file { getattr unlink };
 allow vold_prepare_subdirs apex_mnt_dir:dir { open read };
 allow vold_prepare_subdirs mnt_expand_file:dir search;
-allow vold_prepare_subdirs user_profile_data_file:dir { search getattr relabelfrom relabelto };
+allow vold_prepare_subdirs user_profile_data_file:dir { search getattr relabelfrom };
+allow vold_prepare_subdirs user_profile_root_file:dir { search getattr relabelfrom relabelto };
 # /data/misc is unlabeled during early boot.
 allow vold_prepare_subdirs unlabeled:dir search;
 
diff --git a/private/zygote.te b/private/zygote.te
index d3d08bf..577ace8 100644
--- a/private/zygote.te
+++ b/private/zygote.te
@@ -61,7 +61,7 @@
 allow zygote mnt_expand_file:dir { open read search relabelto };
 
 # Bind mount subdirectories on /data/misc/profiles/cur
-allow zygote { user_profile_data_file }:dir { mounton search };
+allow zygote user_profile_root_file:dir { mounton search };
 
 # Create and bind dirs on /data/data
 allow zygote tmpfs:dir { create_dir_perms mounton };