From ab72ec5d5db6239197e1cfa5e9c3692c4399e1f6 Mon Sep 17 00:00:00 2001 From: Andrew Scull Date: Mon, 14 Mar 2022 09:10:52 +0000 Subject: [PATCH] Strict instance boot checks When strict boot is active, ensure the instance image is provisioned during the first, and only the first, boot of the instance. This prevents and instance from being forked. Bug: 217376291 Test: atest MicrodroidTests Change-Id: I648b7df3b3368a3766f9f4e76b8f70f59d05659a --- microdroid_manager/src/main.rs | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs index b6442857..9e159d2a 100644 --- a/microdroid_manager/src/main.rs +++ b/microdroid_manager/src/main.rs @@ -61,6 +61,8 @@ const EXTRA_IDSIG_PATH_PATTERN: &str = "/dev/block/by-name/extra-idsig-*"; 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"; +const AVF_STRICT_BOOT: &str = "/sys/firmware/devicetree/base/chosen/avf,strict-boot"; +const AVF_NEW_INSTANCE: &str = "/sys/firmware/devicetree/base/chosen/avf,new-instance"; /// The CID representing the host VM const VMADDR_CID_HOST: u32 = 2; @@ -193,12 +195,35 @@ fn dice_derivation(verified_data: MicrodroidData, payload_config_path: &str) -> Ok(()) } +fn is_strict_boot() -> bool { + Path::new(AVF_STRICT_BOOT).exists() +} + +fn is_new_instance() -> bool { + Path::new(AVF_NEW_INSTANCE).exists() +} + fn try_run_payload(service: &Strong) -> Result { let metadata = load_metadata().context("Failed to load payload metadata")?; let mut instance = InstanceDisk::new().context("Failed to load instance.img")?; let saved_data = instance.read_microdroid_data().context("Failed to read identity data")?; + if is_strict_boot() { + // Provisioning must happen on the first boot and never again. + if is_new_instance() { + ensure!( + saved_data.is_none(), + MicrodroidError::InvalidConfig("Found instance data on first boot.".to_string()) + ); + } else { + ensure!( + saved_data.is_some(), + MicrodroidError::InvalidConfig("Instance data not found.".to_string()) + ); + }; + } + // Verify the payload before using it. let verified_data = verify_payload(&metadata, saved_data.as_ref()).context("Payload verification failed")?;