Full sepolicy for gsid.

Bug: 122556707
Test: manual test
Change-Id: I2536deefb3aa75deee4aeae7df074349b705b0f0
diff --git a/private/compat/28.0/28.0.ignore.cil b/private/compat/28.0/28.0.ignore.cil
index abb796f..6c97fe2 100644
--- a/private/compat/28.0/28.0.ignore.cil
+++ b/private/compat/28.0/28.0.ignore.cil
@@ -48,6 +48,8 @@
     flags_health_check_exec
     fwk_bufferhub_hwservice
     fwk_stats_hwservice
+    gsi_data_file
+    gsi_metadata_file
     gsi_service
     gsid
     gsid_exec
diff --git a/private/file_contexts b/private/file_contexts
index d616285..233d5f4 100644
--- a/private/file_contexts
+++ b/private/file_contexts
@@ -438,6 +438,7 @@
 /data/app/vmdl[^/]+\.tmp/oat(/.*)?           u:object_r:dalvikcache_data_file:s0
 /data/app-private(/.*)?               u:object_r:apk_private_data_file:s0
 /data/app-private/vmdl.*\.tmp(/.*)?   u:object_r:apk_private_tmp_file:s0
+/data/gsi(/.*)?        u:object_r:gsi_data_file:s0
 /data/tombstones(/.*)?	u:object_r:tombstone_data_file:s0
 /data/vendor/tombstones/wifi(/.*)? u:object_r:tombstone_wifi_data_file:s0
 /data/local/tmp(/.*)?	u:object_r:shell_data_file:s0
@@ -612,6 +613,7 @@
 #
 /metadata(/.*)?           u:object_r:metadata_file:s0
 /metadata/vold(/.*)?      u:object_r:vold_metadata_file:s0
+/metadata/gsi(/.*)?       u:object_r:gsi_metadata_file:s0
 
 #############################
 # asec containers
diff --git a/private/gsid.te b/private/gsid.te
index 5ac1c25..0c2e50c 100644
--- a/private/gsid.te
+++ b/private/gsid.te
@@ -7,4 +7,101 @@
 init_daemon_domain(gsid)
 
 binder_use(gsid)
+binder_service(gsid)
 add_service(gsid, gsi_service)
+
+# Needed to create/delete device-mapper nodes, and read/write to them.
+allow gsid dm_device:chr_file rw_file_perms;
+allow gsid dm_device:blk_file rw_file_perms;
+allow gsid self:global_capability_class_set sys_admin;
+dontaudit gsid self:global_capability_class_set dac_override;
+
+# libfiemap_writer uses sysfs to derive the bottom of a device-mapper stacking.
+# This requires traversing /sys/block/dm-N/slaves/* and reading the list of
+# file names.
+allow gsid sysfs_dm:dir r_dir_perms;
+
+# Needed to stat /data/gsi/* and realpath on /dev/block/by-name/*
+allow gsid block_device:dir r_dir_perms;
+
+# liblp queries these block alignment properties.
+allowxperm gsid userdata_block_device:blk_file ioctl {
+  BLKIOMIN
+  BLKALIGNOFF
+};
+
+# gsi_tool passes the system image over the adb connection, via stdin.
+allow gsid adbd:fd use;
+
+# gsid needs to store images on /data, but cannot use file I/O. If it did, the
+# underlying blocks would be encrypted, and we couldn't mount the GSI image in
+# first-stage init. So instead of directly writing to /data, we:
+#
+#   1. fallocate a file large enough to hold the signed GSI
+#   2. extract its block layout with FIEMAP
+#   3. create a dm-linear device using the FIEMAP, targeting /dev/block/by-name/userdata
+#   4. write system_gsi into that dm device
+#
+# To make this process work, we need to unwrap the device-mapper stacking for
+# userdata to reach the underlying block device. To verify the result we use
+# stat(), which requires read access.
+allow gsid userdata_block_device:blk_file r_file_perms;
+
+# gsid uses /metadata/gsi to communicate GSI boot information to first-stage
+# init. It cannot use userdata since data cannot be decrypted during this
+# stage.
+#
+# gsid uses /metadata/gsi to store three files:
+#   install_status - A short string indicating whether a GSI image is bootable.
+#   lp_metadata    - LpMetadata blob describing the block ranges on userdata
+#                    where system_gsi resides.
+#   booted         - An empty file that, if exists, indicates that a GSI is
+#                    currently running.
+#
+allow gsid metadata_file:dir search;
+allow gsid gsi_metadata_file:dir rw_dir_perms;
+allow gsid gsi_metadata_file:file create_file_perms;
+
+allow gsid gsi_data_file:dir rw_dir_perms;
+allow gsid gsi_data_file:file create_file_perms;
+allowxperm gsid gsi_data_file:file ioctl FS_IOC_FIEMAP;
+
+neverallow {
+    domain
+    -init
+    -gsid
+    -fastbootd
+    -vold
+} gsi_metadata_file:dir *;
+
+neverallow {
+    domain
+    -init
+    -gsid
+    -fastbootd
+    -vold
+} gsi_metadata_file:notdevfile_class_set ~{ relabelto getattr };
+
+neverallow {
+    domain
+    -init
+    -gsid
+    -fastbootd
+    -vold
+} { gsi_data_file gsi_metadata_file }:notdevfile_class_set *;
+
+neverallow {
+    domain
+    -gsid
+} gsi_data_file:dir ~{ open create read getattr setattr search relabelto ioctl };
+
+neverallow {
+    domain
+    -init
+    -gsid
+} gsi_data_file:dir *;
+
+neverallow {
+    domain
+    -gsid
+} gsi_data_file:notdevfile_class_set ~{ relabelto getattr };
diff --git a/public/fastbootd.te b/public/fastbootd.te
index 1d77fd1..5827c50 100644
--- a/public/fastbootd.te
+++ b/public/fastbootd.te
@@ -47,6 +47,13 @@
     userdata_block_device
   }:blk_file { w_file_perms getattr ioctl };
 
+  # For disabling/wiping GSI.
+  allow fastbootd metadata_block_device:blk_file r_file_perms;
+  allow fastbootd {rootfs tmpfs}:dir mounton;
+  allow fastbootd metadata_file:dir search;
+  allow fastbootd gsi_metadata_file:dir r_dir_perms;
+  allow fastbootd gsi_metadata_file:file rw_file_perms;
+
   allowxperm fastbootd {
     system_block_device
     super_block_device
diff --git a/public/file.te b/public/file.te
index a8f113b..073be04 100644
--- a/public/file.te
+++ b/public/file.te
@@ -190,6 +190,8 @@
 type metadata_file, file_type;
 # Vold files within /metadata
 type vold_metadata_file, file_type;
+# GSI files within /metadata
+type gsi_metadata_file, file_type;
 
 # Type for /dev/cpu_variant:.*.
 type dev_cpu_variant, file_type;
@@ -328,6 +330,7 @@
 type update_engine_log_data_file, file_type, data_file_type, core_data_file_type;
 # /data/misc/trace for method traces on userdebug / eng builds
 type method_trace_data_file, file_type, data_file_type, core_data_file_type, mlstrustedobject;
+type gsi_data_file, file_type, data_file_type, core_data_file_type;
 
 # /data/data subdirectories - app sandboxes
 type app_data_file, file_type, data_file_type, core_data_file_type;
diff --git a/public/init.te b/public/init.te
index 67e6efa..02302b2 100644
--- a/public/init.te
+++ b/public/init.te
@@ -173,6 +173,7 @@
   file_type
   -app_data_file
   -exec_type
+  -gsi_data_file
   -iorapd_data_file
   -keystore_data_file
   -misc_logd_file
@@ -189,6 +190,7 @@
   file_type
   -app_data_file
   -exec_type
+  -gsi_data_file
   -iorapd_data_file
   -keystore_data_file
   -misc_logd_file
@@ -206,6 +208,7 @@
   file_type
   -app_data_file
   -exec_type
+  -gsi_data_file
   -iorapd_data_file
   -keystore_data_file
   -misc_logd_file
@@ -223,6 +226,7 @@
   -apex_mnt_dir
   -app_data_file
   -exec_type
+  -gsi_data_file
   -iorapd_data_file
   -keystore_data_file
   -misc_logd_file
diff --git a/public/vendor_init.te b/public/vendor_init.te
index b7c60c6..ba0941e 100644
--- a/public/vendor_init.te
+++ b/public/vendor_init.te
@@ -53,6 +53,7 @@
   -unlabeled
   -vendor_file_type
   -vold_metadata_file
+  -gsi_metadata_file
 }:dir { create search getattr open read setattr ioctl write add_name remove_name rmdir relabelfrom };
 
 allow vendor_init unlabeled:{ dir notdevfile_class_set } { getattr relabelfrom };
@@ -66,6 +67,7 @@
   -unlabeled
   -vendor_file_type
   -vold_metadata_file
+  -gsi_metadata_file
 }:file { create getattr open read write setattr relabelfrom unlink map };
 
 allow vendor_init {
@@ -76,6 +78,7 @@
   -unlabeled
   -vendor_file_type
   -vold_metadata_file
+  -gsi_metadata_file
 }:{ sock_file fifo_file } { create getattr open read setattr relabelfrom unlink };
 
 allow vendor_init {
@@ -87,6 +90,7 @@
   -unlabeled
   -vendor_file_type
   -vold_metadata_file
+  -gsi_metadata_file
 }:lnk_file { create getattr setattr relabelfrom unlink };
 
 allow vendor_init {
@@ -97,6 +101,7 @@
   -system_file_type
   -vendor_file_type
   -vold_metadata_file
+  -gsi_metadata_file
 }:dir_file_class_set relabelto;
 
 allow vendor_init dev_type:dir create_dir_perms;
diff --git a/public/vold.te b/public/vold.te
index c540dd2..801c2de 100644
--- a/public/vold.te
+++ b/public/vold.te
@@ -240,6 +240,10 @@
 
 dontaudit vold self:global_capability_class_set sys_resource;
 
+# vold needs to know whether we're running a GSI.
+allow vold gsi_metadata_file:dir r_dir_perms;
+allow vold gsi_metadata_file:file r_file_perms;
+
 neverallow {
     domain
     -vold