Allocate each VM an instance_id
Introduce a 64 bytes' long instance_id. When the VM is created, this is
requested from virtualization service, which randomly allocates it.
While it does that, it also logs the user & the package name.
The app persists this allocated instance_id in a file `instance_id` in
its directory for the vm instance (along with instance.img &
storage.img). When the VirtualMachine is run, this is an input into the
VM via DT.
This patch modifies Compos & vm binary to work with the instance_id.
flagging: instance_id allocation request is conditional to flag build
time flag llpvm_changes, no file `instance_id` is created if the flag is
off. `instanceId` is all 0s if the flag is off.
Bug: 291213394
Test: atest MicrodroidHostTest
Test: atest MicrodroidTests
Test: atest ComposHostTestCases
Test: Look for instance_id logged by VS
Change-Id: Ie8e25b9510e27362d4580c55c1bd557143ff7d0e
diff --git a/compos/common/compos_client.rs b/compos/common/compos_client.rs
index abaa74c..077a0ef 100644
--- a/compos/common/compos_client.rs
+++ b/compos/common/compos_client.rs
@@ -72,6 +72,7 @@
/// Start a new CompOS VM instance using the specified instance image file and parameters.
pub fn start(
service: &dyn IVirtualizationService,
+ instance_id: [u8; 64],
instance_image: File,
idsig: &Path,
idsig_manifest_apk: &Path,
@@ -121,6 +122,7 @@
name: parameters.name.clone(),
apk: Some(apk_fd),
idsig: Some(idsig_fd),
+ instanceId: instance_id,
instanceImage: Some(instance_fd),
encryptedStorageImage: None,
payload: Payload::ConfigPath(config_path),
diff --git a/compos/common/lib.rs b/compos/common/lib.rs
index 1f937c9..9d90717 100644
--- a/compos/common/lib.rs
+++ b/compos/common/lib.rs
@@ -39,6 +39,9 @@
/// tests.
pub const TEST_INSTANCE_DIR: &str = "test";
+/// The file that holds the instance_id of CompOS instance.
+pub const INSTANCE_ID_FILE: &str = "instance_id";
+
/// The file that holds the instance image for a CompOS instance.
pub const INSTANCE_IMAGE_FILE: &str = "instance.img";
diff --git a/compos/composd/src/instance_starter.rs b/compos/composd/src/instance_starter.rs
index 457520f..76001a4 100644
--- a/compos/composd/src/instance_starter.rs
+++ b/compos/composd/src/instance_starter.rs
@@ -20,13 +20,13 @@
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::{
IVirtualizationService::IVirtualizationService, PartitionType::PartitionType,
};
-use anyhow::{Context, Result};
+use anyhow::{anyhow, Context, Result};
use binder::{LazyServiceGuard, ParcelFileDescriptor, Strong};
use compos_aidl_interface::aidl::com::android::compos::ICompOsService::ICompOsService;
use compos_common::compos_client::{ComposClient, VmParameters};
use compos_common::{
COMPOS_DATA_ROOT, IDSIG_FILE, IDSIG_MANIFEST_APK_FILE, IDSIG_MANIFEST_EXT_APK_FILE,
- INSTANCE_IMAGE_FILE,
+ INSTANCE_ID_FILE, INSTANCE_IMAGE_FILE,
};
use log::info;
use std::fs;
@@ -66,6 +66,7 @@
pub struct InstanceStarter {
instance_name: String,
instance_root: PathBuf,
+ instance_id_file: PathBuf,
instance_image: PathBuf,
idsig: PathBuf,
idsig_manifest_apk: PathBuf,
@@ -77,6 +78,7 @@
pub fn new(instance_name: &str, vm_parameters: VmParameters) -> Self {
let instance_root = Path::new(COMPOS_DATA_ROOT).join(instance_name);
let instance_root_path = instance_root.as_path();
+ let instance_id_file = instance_root_path.join(INSTANCE_ID_FILE);
let instance_image = instance_root_path.join(INSTANCE_IMAGE_FILE);
let idsig = instance_root_path.join(IDSIG_FILE);
let idsig_manifest_apk = instance_root_path.join(IDSIG_MANIFEST_APK_FILE);
@@ -84,6 +86,7 @@
Self {
instance_name: instance_name.to_owned(),
instance_root,
+ instance_id_file,
instance_image,
idsig,
idsig_manifest_apk,
@@ -103,7 +106,10 @@
// Overwrite any existing instance - it's unlikely to be valid with the current set
// of APEXes, and finding out it isn't is much more expensive than creating a new one.
self.create_instance_image(virtualization_service)?;
-
+ // TODO(b/294177871): Ping VS to delete the old instance's secret.
+ if cfg!(llpvm_changes) {
+ self.allocate_instance_id(virtualization_service)?;
+ }
// Delete existing idsig files. Ignore error in case idsig doesn't exist.
let _ignored1 = fs::remove_file(&self.idsig);
let _ignored2 = fs::remove_file(&self.idsig_manifest_apk);
@@ -122,6 +128,14 @@
&self,
virtualization_service: &dyn IVirtualizationService,
) -> Result<CompOsInstance> {
+ let instance_id: [u8; 64] = if cfg!(llpvm_changes) {
+ fs::read(&self.instance_id_file)?
+ .try_into()
+ .map_err(|_| anyhow!("Failed to get instance_id"))?
+ } else {
+ [0u8; 64]
+ };
+
let instance_image = fs::OpenOptions::new()
.read(true)
.write(true)
@@ -129,6 +143,7 @@
.context("Failed to open instance image")?;
let vm_instance = ComposClient::start(
virtualization_service,
+ instance_id,
instance_image,
&self.idsig,
&self.idsig_manifest_apk,
@@ -164,4 +179,13 @@
.context("Writing instance image file")?;
Ok(())
}
+
+ fn allocate_instance_id(
+ &self,
+ virtualization_service: &dyn IVirtualizationService,
+ ) -> Result<()> {
+ let id = virtualization_service.allocateInstanceId().context("Allocating Instance Id")?;
+ fs::write(&self.instance_id_file, id)?;
+ Ok(())
+ }
}
diff --git a/compos/verify/verify.rs b/compos/verify/verify.rs
index 567083d..a3f18d5 100644
--- a/compos/verify/verify.rs
+++ b/compos/verify/verify.rs
@@ -18,7 +18,7 @@
//! public key. The tool is intended to be run by odsign during boot.
use android_logger::LogId;
-use anyhow::{bail, Context, Result};
+use anyhow::{anyhow, bail, Context, Result};
use binder::ProcessState;
use clap::{Parser, ValueEnum};
use compos_common::compos_client::{ComposClient, VmCpuTopology, VmParameters};
@@ -28,9 +28,10 @@
};
use compos_common::{
COMPOS_DATA_ROOT, CURRENT_INSTANCE_DIR, IDSIG_FILE, IDSIG_MANIFEST_APK_FILE,
- IDSIG_MANIFEST_EXT_APK_FILE, INSTANCE_IMAGE_FILE, TEST_INSTANCE_DIR,
+ IDSIG_MANIFEST_EXT_APK_FILE, INSTANCE_ID_FILE, INSTANCE_IMAGE_FILE, TEST_INSTANCE_DIR,
};
use log::error;
+use std::fs;
use std::fs::File;
use std::io::Read;
use std::panic;
@@ -90,11 +91,17 @@
bail!("{:?} is not a directory", instance_dir);
}
+ let instance_id_file = instance_dir.join(INSTANCE_ID_FILE);
let instance_image = instance_dir.join(INSTANCE_IMAGE_FILE);
let idsig = instance_dir.join(IDSIG_FILE);
let idsig_manifest_apk = instance_dir.join(IDSIG_MANIFEST_APK_FILE);
let idsig_manifest_ext_apk = instance_dir.join(IDSIG_MANIFEST_EXT_APK_FILE);
+ let instance_id: [u8; 64] = if cfg!(llpvm_changes) {
+ fs::read(instance_id_file)?.try_into().map_err(|_| anyhow!("Failed to get instance_id"))?
+ } else {
+ [0u8; 64]
+ };
let instance_image = File::open(instance_image).context("Failed to open instance image")?;
let info = artifacts_dir.join("compos.info");
@@ -110,6 +117,7 @@
let virtualization_service = virtmgr.connect()?;
let vm_instance = ComposClient::start(
&*virtualization_service,
+ instance_id,
instance_image,
&idsig,
&idsig_manifest_apk,