Root of /data belongs to init (re-landing)

Give /data itself a different label to its contents, to ensure that
only init creates files and directories there.

This change originally landed as aosp/1106014 and was reverted in
aosp/1116238 to fix b/140402208. aosp/1116298 fixes the underlying
problem, and with that we can re-land this change.

Bug: 139190159
Bug: 140402208
Test: aosp boots, logs look good
Change-Id: I1a366c577a0fff307ca366a6844231bcf8afe3bf
diff --git a/private/compat/29.0/29.0.cil b/private/compat/29.0/29.0.cil
index 86f8a8d..2079248 100644
--- a/private/compat/29.0/29.0.cil
+++ b/private/compat/29.0/29.0.cil
@@ -1780,7 +1780,7 @@
 (typeattributeset system_block_device_29_0 (system_block_device))
 (typeattributeset system_boot_reason_prop_29_0 (system_boot_reason_prop))
 (typeattributeset system_bootstrap_lib_file_29_0 (system_bootstrap_lib_file))
-(typeattributeset system_data_file_29_0 (system_data_file))
+(typeattributeset system_data_file_29_0 (system_data_file system_data_root_file))
 (typeattributeset system_event_log_tags_file_29_0 (system_event_log_tags_file))
 (typeattributeset system_file_29_0 (system_file))
 (typeattributeset systemkeys_data_file_29_0 (systemkeys_data_file))
diff --git a/private/file_contexts b/private/file_contexts
index 3740218..1e9549c 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -436,7 +436,8 @@
 # NOTE: When modifying existing label rules, changes may also need to
 # propagate to the "Expanded data files" section.
 #
-/data(/.*)?		u:object_r:system_data_file:s0
+/data		u:object_r:system_data_root_file:s0
+/data/(.*)?		u:object_r:system_data_file:s0
 /data/system/packages\.list u:object_r:packages_list_file:s0
 /data/unencrypted(/.*)?         u:object_r:unencrypted_data_file:s0
 /data/backup(/.*)?		u:object_r:backup_data_file:s0
diff --git a/private/perfetto.te b/private/perfetto.te
index 419c4b9..e95defa 100644
--- a/private/perfetto.te
+++ b/private/perfetto.te
@@ -69,6 +69,7 @@
 neverallow perfetto {
   data_file_type
   -system_data_file
+  -system_data_root_file
   # TODO(b/72998741) Remove exemption. Further restricted in a subsequent
   # neverallow. Currently only getattr and search are allowed.
   -vendor_data_file
diff --git a/private/traced.te b/private/traced.te
index 2d7d07f..42c6704 100644
--- a/private/traced.te
+++ b/private/traced.te
@@ -62,6 +62,7 @@
 neverallow traced {
   data_file_type
   -system_data_file
+  -system_data_root_file
   # TODO(b/72998741) Remove vendor_data_file exemption. Further restricted in a
   # subsequent neverallow. Currently only getattr and search are allowed.
   -vendor_data_file
diff --git a/private/traced_probes.te b/private/traced_probes.te
index 8746c34..97a7e6e 100644
--- a/private/traced_probes.te
+++ b/private/traced_probes.te
@@ -101,6 +101,7 @@
   -apk_data_file
   -dalvikcache_data_file
   -system_data_file
+  -system_data_root_file
   -system_app_data_file
   -backup_data_file
   -bootstat_data_file
diff --git a/private/vendor_init.te b/private/vendor_init.te
index 50efc22..6a68f1f 100644
--- a/private/vendor_init.te
+++ b/private/vendor_init.te
@@ -2,3 +2,6 @@
 # Sometimes we have to write to non-existent files to avoid conditional
 # init behavior. See b/35303861 for an example.
 dontaudit vendor_init sysfs:dir write;
+
+# TODO(b/140259336) We want to remove vendor_init in the long term but allow for now
+allow vendor_init system_data_root_file:dir rw_dir_perms;
diff --git a/public/domain.te b/public/domain.te
index 29e007d..b4b5475 100644
--- a/public/domain.te
+++ b/public/domain.te
@@ -222,8 +222,9 @@
   allow domain system_data_file:dir getattr;
 ')
 allow { coredomain appdomain } system_data_file:dir getattr;
-# /data has the label system_data_file. Vendor components need the search
-# permission on system_data_file for path traversal to /data/vendor.
+# /data has the label system_data_root_file. Vendor components need the search
+# permission on system_data_root_file for path traversal to /data/vendor.
+allow domain system_data_root_file:dir { search getattr } ;
 allow domain system_data_file:dir search;
 # TODO restrict this to non-coredomain
 allow domain vendor_data_file:dir { getattr search };
@@ -858,6 +859,7 @@
   } {
     core_data_file_type
     -system_data_file # default label for files on /data. Covered below...
+    -system_data_root_file
     -vendor_data_file
     -zoneinfo_data_file
     with_native_coverage(`-method_trace_data_file')
@@ -869,6 +871,7 @@
     core_data_file_type
     -unencrypted_data_file
     -system_data_file
+    -system_data_root_file
     -vendor_data_file
     -zoneinfo_data_file
     with_native_coverage(`-method_trace_data_file')
diff --git a/public/file.te b/public/file.te
index 2758cad..45c2fbc 100644
--- a/public/file.te
+++ b/public/file.te
@@ -228,6 +228,8 @@
 type cgroup_rc_file, file_type;
 # /cores for coredumps on userdebug / eng builds
 type coredump_file, file_type;
+# Type of /data itself
+type system_data_root_file, file_type, data_file_type, core_data_file_type;
 # Default type for anything under /data.
 type system_data_file, file_type, data_file_type, core_data_file_type;
 # Type for /data/system/packages.list.
diff --git a/public/init.te b/public/init.te
index 35fab33..4f8e855 100644
--- a/public/init.te
+++ b/public/init.te
@@ -80,7 +80,18 @@
 
 # Create and mount on directories in /.
 allow init rootfs:dir create_dir_perms;
-allow init { rootfs cache_file cgroup storage_file mnt_user_file system_data_file system_file vendor_file postinstall_mnt_dir }:dir mounton;
+allow init {
+    rootfs
+    cache_file
+    cgroup
+    storage_file
+    mnt_user_file
+    system_data_file
+    system_data_root_file
+    system_file
+    vendor_file
+    postinstall_mnt_dir
+}:dir mounton;
 allow init cgroup_bpf:dir { create mounton };
 
 # Mount bpf fs on sys/fs/bpf
@@ -591,3 +602,7 @@
 
 # No domain should be allowed to ptrace init.
 neverallow * init:process ptrace;
+
+# init owns the root of /data
+# TODO(b/140259336) We want to remove vendor_init in the long term but allow for now
+neverallow { domain -init -vendor_init -vold } system_data_root_file:dir { write add_name remove_name };
diff --git a/public/vold.te b/public/vold.te
index 3a38ba5..f4a6259 100644
--- a/public/vold.te
+++ b/public/vold.te
@@ -135,7 +135,10 @@
 allow vold efs_file:file rw_file_perms;
 
 # Create and mount on /data/tmp_mnt and management of expansion mounts
-allow vold system_data_file:dir { create rw_dir_perms mounton setattr rmdir };
+allow vold {
+    system_data_file
+    system_data_root_file
+}:dir { create rw_dir_perms mounton setattr rmdir };
 allow vold system_data_file:lnk_file getattr;
 
 # Vold create users in /data/vendor_{ce,de}/[0-9]+