Merge "Ignore identity if the debug policy is turned on"
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index fa064a7..531c707 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -18,7 +18,7 @@
mod ioutil;
mod payload;
-use crate::instance::{ApkData, InstanceDisk, MicrodroidData, RootHash};
+use crate::instance::{ApexData, ApkData, InstanceDisk, MicrodroidData, RootHash};
use android_hardware_security_dice::aidl::android::hardware::security::dice::{
Config::Config, InputValues::InputValues, Mode::Mode,
};
@@ -64,6 +64,8 @@
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";
+const DEBUG_MICRODROID_NO_VERIFIED_BOOT: &str =
+ "/sys/firmware/devicetree/base/virtualization/guest/debug-microdroid,no-verified-boot";
/// The CID representing the host VM
const VMADDR_CID_HOST: u32 = 2;
@@ -243,6 +245,10 @@
Path::new(AVF_NEW_INSTANCE).exists()
}
+fn is_verified_boot() -> bool {
+ !Path::new(DEBUG_MICRODROID_NO_VERIFIED_BOOT).exists()
+}
+
fn try_run_payload(service: &Strong<dyn IVirtualMachineService>) -> Result<i32> {
let metadata = load_metadata().context("Failed to load payload metadata")?;
@@ -268,18 +274,29 @@
let verified_data = verify_payload(&metadata, saved_data.as_ref())
.context("Payload verification failed")
.map_err(|e| MicrodroidError::PayloadVerificationFailed(e.to_string()))?;
- if let Some(saved_data) = saved_data {
- ensure!(
- saved_data == verified_data,
- MicrodroidError::PayloadChanged(String::from(
- "Detected an update of the payload which isn't supported yet."
- ))
- );
- info!("Saved data is verified.");
+
+ // In case identity is ignored (by debug policy), we should reuse existing payload data, even
+ // when the payload is changed. This is to keep the derived secret same as before.
+ let verified_data = if let Some(saved_data) = saved_data {
+ if !is_verified_boot() {
+ if saved_data != verified_data {
+ info!("Detected an update of the payload, but continue (regarding debug policy)")
+ }
+ } else {
+ ensure!(
+ saved_data == verified_data,
+ MicrodroidError::PayloadChanged(String::from(
+ "Detected an update of the payload which isn't supported yet."
+ ))
+ );
+ info!("Saved data is verified.");
+ }
+ saved_data
} else {
info!("Saving verified data.");
instance.write_microdroid_data(&verified_data).context("Failed to write identity data")?;
- }
+ verified_data
+ };
// To minimize the exposure to untrusted data, derive dice profile as soon as possible.
info!("DICE derivation for payload");
@@ -371,6 +388,29 @@
.context("Spawn zipfuse")
}
+fn write_apex_payload_data(
+ saved_data: Option<&MicrodroidData>,
+ apex_data_from_payload: &[ApexData],
+) -> Result<()> {
+ if let Some(saved_apex_data) = saved_data.map(|d| &d.apex_data) {
+ // We don't support APEX updates. (assuming that update will change root digest)
+ ensure!(
+ saved_apex_data == apex_data_from_payload,
+ MicrodroidError::PayloadChanged(String::from("APEXes have changed."))
+ );
+ let apex_metadata = to_metadata(apex_data_from_payload);
+ // Pass metadata(with public keys and root digests) to apexd so that it uses the passed
+ // metadata instead of the default one (/dev/block/by-name/payload-metadata)
+ OpenOptions::new()
+ .create_new(true)
+ .write(true)
+ .open("/apex/vm-payload-metadata")
+ .context("Failed to open /apex/vm-payload-metadata")
+ .and_then(|f| write_metadata(&apex_metadata, f))?;
+ }
+ Ok(())
+}
+
// 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
@@ -465,22 +505,13 @@
// While waiting for apkdmverity to mount APK, gathers public keys and root digests from
// APEX payload.
let apex_data_from_payload = get_apex_data_from_payload(metadata)?;
- if let Some(saved_data) = saved_data.map(|d| &d.apex_data) {
- // We don't support APEX updates. (assuming that update will change root digest)
- ensure!(
- saved_data == &apex_data_from_payload,
- MicrodroidError::PayloadChanged(String::from("APEXes have changed."))
- );
- let apex_metadata = to_metadata(&apex_data_from_payload);
- // Pass metadata(with public keys and root digests) to apexd so that it uses the passed
- // metadata instead of the default one (/dev/block/by-name/payload-metadata)
- OpenOptions::new()
- .create_new(true)
- .write(true)
- .open("/apex/vm-payload-metadata")
- .context("Failed to open /apex/vm-payload-metadata")
- .and_then(|f| write_metadata(&apex_metadata, f))?;
+
+ // Writing /apex/vm-payload-metadata is to verify that the payload isn't changed.
+ // Skip writing it if the debug policy ignoring identity is on
+ if is_verified_boot() {
+ write_apex_payload_data(saved_data, &apex_data_from_payload)?;
}
+
// Start apexd to activate APEXes
system_properties::write("ctl.start", "apexd-vm")?;