Microdroid boot process is controlled by microdroid_manager

Previously, the boot process of microdroid was mostly implemented in the
init.rc file. microdroid_manager was started first in the background,
then apexd, apkdmverity, and zipfuse were executed in sequence. However,
in order to correctly implement the app payload verification scheme,
most of the early boot process has to be controlled by
microdroid_manager. Specifically, apkdmverity should be started "after"
the apk roothash is read from the instance disk by microdroid_manager.

As an alternative, we could let apkdmverity the read instance disk by
itself. However, this is undesirable because doing so requires multiple
processes - microdroid_manager and apkdmverity - have access to the
instance disk and more seriously the secret key to decrypt it.

Another alternative is to let microdroid_manager do the dm-verity
configuration which apkdmverity does. This also is considered
undesirable because then we would give the permissions for configuring
dm-verity devices to microdroid_manager which is a long-running daemon
process. Note that apkdmverity is not a daemon process.

This CL introduces a few number of changes which are required to let
microdroid_manager directly control the early boot process:

1) microdroid_manager is allowed to start the services apkdmverity and
zipfuse by using the `ctl.start` sysprop.

2) apkdmverity is allowed to use bootstrap bionic libraries as it is now
executed before APEXd activates the APEXes.

3) A new sysprop `microdroid_manager.apk_roothash` is added. It is
written by microdroid_manager and read by apkdmverity. It contains the
roothash read from the instance disk. This value is not a secret.

4) Another new sysprop `apex_config.done` is added. It is set by init
just after `perform_apex_config` and read by microdroid_manager.
Microdroid_manager uses this to wait until linker configuration is ready
so that it can execute app payloads with the config.

Bug: 193504400
Test: atest MicrodroidHostTestCases
Change-Id: If29ce17d7a6cb4859e8ceeffb321724e7f11bf82
diff --git a/microdroid/system/private/apkdmverity.te b/microdroid/system/private/apkdmverity.te
index 8974a1d..0c0ef41 100644
--- a/microdroid/system/private/apkdmverity.te
+++ b/microdroid/system/private/apkdmverity.te
@@ -6,6 +6,10 @@
 # allow domain transition from init
 init_daemon_domain(apkdmverity)
 
+# apkdmverity is using bootstrap bionic
+allow apkdmverity system_bootstrap_lib_file:dir r_dir_perms;
+allow apkdmverity system_bootstrap_lib_file:file { execute read open getattr map };
+
 # apkdmverity accesses "payload metadata disk" which points to
 # a /dev/vd* block device file.
 allow apkdmverity block_device:dir r_dir_perms;
@@ -20,6 +24,9 @@
 # allow apkdmverity to create loop devices with /dev/loop-control
 allow apkdmverity loop_control_device:chr_file rw_file_perms;
 
+# allow apkdmverity to read the roothash passed from microdroid_manager
+get_prop(apkdmverity, microdroid_manager_roothash_prop)
+
 # allow apkdmverity to access loop devices
 allow apkdmverity loop_device:blk_file rw_file_perms;
 allowxperm apkdmverity loop_device:blk_file ioctl {
diff --git a/microdroid/system/private/domain.te b/microdroid/system/private/domain.te
index a3dfb27..ac5ad6c 100644
--- a/microdroid/system/private/domain.te
+++ b/microdroid/system/private/domain.te
@@ -218,9 +218,13 @@
 allow domain self:global_capability_class_set audit_control;
 allow domain self:netlink_audit_socket { create_socket_perms_no_ioctl nlmsg_write };
 
-# workaround for supressing property accesses.
-# TODO: remove these
-set_prop(domain, property_type -vmsecret_keymint_prop)
+# workaround for suppressing property accesses.
+# TODO(b/199007910): remove these
+set_prop(domain, {
+    property_type
+    -vmsecret_keymint_prop
+    -microdroid_manager_roothash_prop
+})
 # auditallow { domain -init } property_type:property_service set;
 # auditallow { domain -init } property_type:file rw_file_perms;
 
diff --git a/microdroid/system/private/microdroid_manager.te b/microdroid/system/private/microdroid_manager.te
index 893469c..f1d3140 100644
--- a/microdroid/system/private/microdroid_manager.te
+++ b/microdroid/system/private/microdroid_manager.te
@@ -44,4 +44,14 @@
     IOCTL_VM_SOCKETS_GET_LOCAL_CID
 };
 
+# Allow microdroid_manager to start the services apkdmverity and zipfuse
+set_prop(microdroid_manager, ctl_apkdmverity_prop)
+set_prop(microdroid_manager, ctl_zipfuse_prop)
+
+# Allow microdroid_manager to wait for linkerconfig to be ready
+get_prop(microdroid_manager, apex_config_prop)
+
+# Allow microdroid_manager to pass the roothash to apkdmverity
+set_prop(microdroid_manager, microdroid_manager_roothash_prop)
+
 neverallow microdroid_manager { file_type fs_type }:file execute_no_trans;
diff --git a/microdroid/system/private/property.te b/microdroid/system/private/property.te
index d3d413e..58942b6 100644
--- a/microdroid/system/private/property.te
+++ b/microdroid/system/private/property.te
@@ -14,3 +14,18 @@
   -microdroid_manager
   -hal_keymint_server
 } vmsecret_keymint_prop:file no_rw_file_perms;
+
+# microdroid_manager_roothash_prop can only be set by microdroid_manager
+# and read by apkdmverity
+neverallow {
+    domain
+    -init
+    -microdroid_manager
+} microdroid_manager_roothash_prop:property_service set;
+
+neverallow {
+    domain
+    -init
+    -microdroid_manager
+    -apkdmverity
+} microdroid_manager_roothash_prop:file no_rw_file_perms;
diff --git a/microdroid/system/private/property_contexts b/microdroid/system/private/property_contexts
index 61cd68d..f2ce09a 100644
--- a/microdroid/system/private/property_contexts
+++ b/microdroid/system/private/property_contexts
@@ -21,6 +21,9 @@
 
 ctl.stop$apexd u:object_r:ctl_apexd_prop:s0
 
+ctl.start$apkdmverity    u:object_r:ctl_apkdmverity_prop:s0
+ctl.start$zipfuse        u:object_r:ctl_zipfuse_prop:s0
+
 ctl.fuse_   u:object_r:ctl_fuse_prop:s0
 ctl.console u:object_r:ctl_console_prop:s0
 ctl.        u:object_r:ctl_default_prop:s0
@@ -97,3 +100,7 @@
 ro.apex.updatable u:object_r:exported_default_prop:s0 exact bool
 
 keystore.boot_level u:object_r:keystore_listen_prop:s0 exact int
+
+apex_config.done u:object_r:apex_config_prop:s0 exact bool
+
+microdroid_manager.apk_roothash u:object_r:microdroid_manager_roothash_prop:s0 exact string
diff --git a/microdroid/system/public/property.te b/microdroid/system/public/property.te
index f5dc758..577353a 100644
--- a/microdroid/system/public/property.te
+++ b/microdroid/system/public/property.te
@@ -5,6 +5,7 @@
 type cold_boot_done_prop, property_type;
 type ctl_adbd_prop, property_type;
 type ctl_apexd_prop, property_type;
+type ctl_apkdmverity_prop, property_type;
 type ctl_console_prop, property_type;
 type ctl_default_prop, property_type;
 type ctl_fuse_prop, property_type;
@@ -15,6 +16,7 @@
 type ctl_sigstop_prop, property_type;
 type ctl_start_prop, property_type;
 type ctl_stop_prop, property_type;
+type ctl_zipfuse_prop, property_type;
 type debug_prop, property_type;
 type default_prop, property_type;
 type exported_default_prop, property_type;
@@ -31,6 +33,8 @@
 type usb_control_prop, property_type;
 type vendor_default_prop, property_type;
 type vmsecret_keymint_prop, property_type;
+type apex_config_prop, property_type;
+type microdroid_manager_roothash_prop, property_type;
 
 allow property_type tmpfs:filesystem associate;