Run apk mount utils from microdroid_manager
For now, the command for apkdmverity and zipfuse is hard-coded in the
init script file. To support passing extra APKs, microdroid_manager
needs to parse the vm config, and then manually run apkdmverity and
zipfuse with appropriate parameters.
Bug: 205224817
Test: atest MicrodroidHostTestCases ComposHostTestCases
Change-Id: Ieef463a807db63c985b5088dcf609f29ddb3de84
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 2e6fa36..99ebc51 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -33,7 +33,7 @@
use std::fs::{self, File, OpenOptions};
use std::os::unix::io::{FromRawFd, IntoRawFd};
use std::path::Path;
-use std::process::{Command, Stdio};
+use std::process::{Child, Command, Stdio};
use std::str;
use std::time::{Duration, SystemTime};
use vsock::VsockStream;
@@ -43,7 +43,16 @@
};
const WAIT_TIMEOUT: Duration = Duration::from_secs(10);
+const APK_DM_VERITY_ARGUMENT: ApkDmverityArgument = {
+ ApkDmverityArgument {
+ apk: "/dev/block/by-name/microdroid-apk",
+ idsig: "/dev/block/by-name/microdroid-apk-idsig",
+ name: "microdroid-apk",
+ }
+};
const DM_MOUNTED_APK_PATH: &str = "/dev/block/mapper/microdroid-apk";
+const APKDMVERITY_BIN: &str = "/system/bin/apkdmverity";
+const ZIPFUSE_BIN: &str = "/system/bin/zipfuse";
/// The CID representing the host VM
const VMADDR_CID_HOST: u32 = 2;
@@ -135,7 +144,12 @@
}
// Before reading a file from the APK, start zipfuse
- system_properties::write("ctl.start", "zipfuse")?;
+ run_zipfuse(
+ "fscontext=u:object_r:zipfusefs:s0,context=u:object_r:system_file:s0",
+ Path::new("/dev/block/mapper/microdroid-apk"),
+ Path::new("/mnt/apk"),
+ )
+ .context("Failed to run zipfuse")?;
if !metadata.payload_config_path.is_empty() {
let config = load_config(Path::new(&metadata.payload_config_path))?;
@@ -160,6 +174,37 @@
Ok(())
}
+struct ApkDmverityArgument<'a> {
+ apk: &'a str,
+ idsig: &'a str,
+ name: &'a str,
+}
+
+fn run_apkdmverity(args: &[ApkDmverityArgument]) -> Result<Child> {
+ let mut cmd = Command::new(APKDMVERITY_BIN);
+
+ cmd.stdin(Stdio::null()).stdout(Stdio::null()).stderr(Stdio::null());
+
+ for argument in args {
+ cmd.arg("--apk").arg(argument.apk).arg(argument.idsig).arg(argument.name);
+ }
+
+ cmd.spawn().context("Spawn apkdmverity")
+}
+
+fn run_zipfuse(option: &str, zip_path: &Path, mount_dir: &Path) -> Result<Child> {
+ Command::new(ZIPFUSE_BIN)
+ .arg("-o")
+ .arg(option)
+ .arg(zip_path)
+ .arg(mount_dir)
+ .stdin(Stdio::null())
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .spawn()
+ .context("Spawn zipfuse")
+}
+
// Verify payload before executing it. For APK payload, Full verification (which is slow) is done
// when the root_hash values from the idsig file and the instance disk are different. This function
// returns the verified root hash (for APK payload) and pubkeys (for APEX payloads) that can be
@@ -182,7 +227,7 @@
}
// Start apkdmverity and wait for the dm-verify block
- system_properties::write("ctl.start", "apkdmverity")?;
+ let mut apkdmverity_child = run_apkdmverity(&[APK_DM_VERITY_ARGUMENT])?;
// While waiting for apkdmverity to mount APK, gathers public keys and root digests from
// APEX payload.
@@ -206,7 +251,8 @@
// Start apexd to activate APEXes
system_properties::write("ctl.start", "apexd-vm")?;
- ioutil::wait_for_file(DM_MOUNTED_APK_PATH, WAIT_TIMEOUT)?;
+ // TODO(inseob): add timeout
+ apkdmverity_child.wait()?;
// Do the full verification if the root_hash is un-trustful. This requires the full scanning of
// the APK file and therefore can be very slow if the APK is large. Note that this step is