Actually derive microdroid vendor dice node
The derive_microdroid_vendor_dice_node binary gets the current dice
chain from the /dev/open-dice0 driver, derives the new dice chain with
the microdroid vendor node and writes it to the
/microdroid_resources/dice_chain.raw file.
The microdroid_manager will read the dice chain from
/microdroid_resources/dice_chain.raw and derive the final dice chain
with the payload node. After the derivation is done, microdroid_manager
will delete the /microdroid_resources/dice_chain.raw file.
Additionally, since /microdroid_resources is mounted in first_stage_init
which happens before selinux is configured, we also call the
restorecon_recursive /microdroid_resources before starting
microdroid_manager to make sure that the /microdroid_resources and
/microdroid_resources/dice_chain.raw have correct context.
Bug: 287593065
Test: run microdroid with vendor partition
Test: atest MicrodroidTests
Change-Id: Ibeb05b0ed24610624b11ac2c3e907cc900bd4cab
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 2386bd4..7da9ea4 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -43,6 +43,7 @@
use log::{error, info};
use microdroid_metadata::{Metadata, PayloadMetadata};
use microdroid_payload_config::{ApkConfig, OsConfig, Task, TaskType, VmPayloadConfig};
+use nix::mount::{umount2, MntFlags};
use nix::sys::signal::Signal;
use payload::load_metadata;
use rpcbinder::RpcSession;
@@ -86,6 +87,8 @@
const ENCRYPTEDSTORE_BACKING_DEVICE: &str = "/dev/block/by-name/encryptedstore";
const ENCRYPTEDSTORE_KEYSIZE: usize = 32;
+const DICE_CHAIN_FILE: &str = "/microdroid_resources/dice_chain.raw";
+
#[derive(thiserror::Error, Debug)]
enum MicrodroidError {
#[error("Cannot connect to virtualization service: {0}")]
@@ -301,8 +304,13 @@
vm_payload_service_fd: OwnedFd,
) -> Result<i32> {
let metadata = load_metadata().context("Failed to load payload metadata")?;
- let dice = DiceDriver::new(Path::new("/dev/open-dice0"), is_strict_boot())
- .context("Failed to load DICE")?;
+ let dice = if Path::new(DICE_CHAIN_FILE).exists() {
+ DiceDriver::from_file(Path::new(DICE_CHAIN_FILE))
+ .context("Failed to load DICE from file")?
+ } else {
+ DiceDriver::new(Path::new("/dev/open-dice0"), is_strict_boot())
+ .context("Failed to load DICE from driver")?
+ };
// Microdroid skips checking payload against instance image iff the device supports
// secretkeeper. In that case Microdroid use VmSecret::V2, which provide protection against
@@ -328,6 +336,10 @@
// Start apexd to activate APEXes. This may allow code within them to run.
system_properties::write("ctl.start", "apexd-vm")?;
+
+ // Unmounting /microdroid_resources is a defence-in-depth effort to ensure that payload
+ // can't get hold of dice chain stored there.
+ umount2("/microdroid_resources", MntFlags::MNT_DETACH)?;
}
// Run encryptedstore binary to prepare the storage