Merge "Switch to tombstoned.microdroid"
diff --git a/compos/benchmark/AndroidTest.xml b/compos/benchmark/AndroidTest.xml
index 0b6d0b1..f98b743 100644
--- a/compos/benchmark/AndroidTest.xml
+++ b/compos/benchmark/AndroidTest.xml
@@ -27,11 +27,6 @@
<option name="force-root" value="true" />
</target_preparer>
- <target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
- <!-- Run in single thread to avoid nondeterministics. -->
- <option name="set-property" key="dalvik.vm.boot-dex2oat-threads" value="1" />
- </target_preparer>
-
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
<option name="package" value="com.android.compos.benchmark" />
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
diff --git a/microdroid/vm_payload/include/vm_payload.h b/microdroid/vm_payload/include/vm_payload.h
index 4ed07b8..6e065a5 100644
--- a/microdroid/vm_payload/include/vm_payload.h
+++ b/microdroid/vm_payload/include/vm_payload.h
@@ -49,8 +49,7 @@
/**
* Get the VM's DICE attestation chain.
*
- * TODO: don't expose the contained privacy breaking identifiers to the payload
- * TODO: keep the DICE chain as an internal detail for as long as possible
+ * This function will fail if the use of restricted APIs is not permitted.
*
* \param data pointer to size bytes where the chain is written.
* \param size number of bytes that can be written to data.
@@ -63,7 +62,7 @@
/**
* Get the VM's DICE attestation CDI.
*
- * TODO: don't expose the raw CDI, only derived values
+ * This function will fail if the use of restricted APIs is not permitted.
*
* \param data pointer to size bytes where the CDI is written.
* \param size number of bytes that can be written to data.
diff --git a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
index d3ebe5c..4dd3db6 100644
--- a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
+++ b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
@@ -39,18 +39,23 @@
/**
* Gets the DICE attestation chain for the VM.
*
- * STOPSHIP:
- * TODO: don't expose this to untrusted payloads as it contains privacy breaking identifiers.
+ * The DICE chain must not be made available to all VMs as it contains privacy breaking
+ * identifiers.
+ *
+ * @return the VM's raw DICE certificate chain.
+ * @throws SecurityException if the use of test APIs is not permitted.
*/
byte[] getDiceAttestationChain();
/**
* Gets the DICE attestation CDI for the VM.
*
- * STOPSHIP:
- * TODO: A better API would handle key derivation on behalf of the payload so they can't forget
- * to do it themselves. It also means the payload doesn't get the raw CDI so there's less chance
- * of it leaking.
+ * The raw attestation CDI isn't very useful but is used for smoke tests. A better API would
+ * handle key derivation on behalf of the payload so they can't forget to do it themselves and
+ * would also mean the payload doesn't get the raw CDI which reduces the chance of it leaking.
+ *
+ * @return the VM's raw attestation CDI.
+ * @throws SecurityException if the use of test APIs is not permitted.
*/
byte[] getDiceAttestationCdi();
}
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 748b497..00c3dce 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -404,6 +404,13 @@
)
.context("Failed to run zipfuse")?;
+ // Restricted APIs are only allowed to be used by platform or test components. Infer this from
+ // the use of a VM config file since those can only be used by platform and test components.
+ let allow_restricted_apis = match payload_metadata {
+ PayloadMetadata::config_path(_) => true,
+ PayloadMetadata::config(_) => false,
+ };
+
let config = load_config(payload_metadata).context("Failed to load payload metadata")?;
let task = config
@@ -439,7 +446,7 @@
// Wait until zipfuse has mounted the APK so we can access the payload
wait_for_property_true(APK_MOUNT_DONE_PROP).context("Failed waiting for APK mount done")?;
- register_vm_payload_service(service.clone(), dice)?;
+ register_vm_payload_service(allow_restricted_apis, service.clone(), dice)?;
ProcessState::start_thread_pool();
system_properties::write("dev.bootcomplete", "1").context("set dev.bootcomplete")?;
diff --git a/microdroid_manager/src/vm_payload_service.rs b/microdroid_manager/src/vm_payload_service.rs
index 4b47ad9..159bf67 100644
--- a/microdroid_manager/src/vm_payload_service.rs
+++ b/microdroid_manager/src/vm_payload_service.rs
@@ -26,6 +26,7 @@
/// Implementation of `IVmPayloadService`.
struct VmPayloadService {
+ allow_restricted_apis: bool,
virtual_machine_service: Strong<dyn IVirtualMachineService>,
dice: DiceContext,
}
@@ -54,10 +55,12 @@
}
fn getDiceAttestationChain(&self) -> binder::Result<Vec<u8>> {
+ self.check_restricted_apis_allowed()?;
Ok(self.dice.bcc.clone())
}
fn getDiceAttestationCdi(&self) -> binder::Result<Vec<u8>> {
+ self.check_restricted_apis_allowed()?;
Ok(self.dice.cdi_attest.to_vec())
}
}
@@ -66,18 +69,32 @@
impl VmPayloadService {
/// Creates a new `VmPayloadService` instance from the `IVirtualMachineService` reference.
- fn new(vm_service: Strong<dyn IVirtualMachineService>, dice: DiceContext) -> Self {
- Self { virtual_machine_service: vm_service, dice }
+ fn new(
+ allow_restricted_apis: bool,
+ vm_service: Strong<dyn IVirtualMachineService>,
+ dice: DiceContext,
+ ) -> Self {
+ Self { allow_restricted_apis, virtual_machine_service: vm_service, dice }
+ }
+
+ fn check_restricted_apis_allowed(&self) -> binder::Result<()> {
+ if self.allow_restricted_apis {
+ Ok(())
+ } else {
+ error!("Use of restricted APIs is not allowed");
+ Err(Status::new_exception_str(ExceptionCode::SECURITY, Some("Use of restricted APIs")))
+ }
}
}
/// Registers the `IVmPayloadService` service.
pub(crate) fn register_vm_payload_service(
+ allow_restricted_apis: bool,
vm_service: Strong<dyn IVirtualMachineService>,
dice: DiceContext,
) -> Result<()> {
let vm_payload_binder = BnVmPayloadService::new_binder(
- VmPayloadService::new(vm_service, dice),
+ VmPayloadService::new(allow_restricted_apis, vm_service, dice),
BinderFeatures::default(),
);
add_service(VM_PAYLOAD_SERVICE_NAME, vm_payload_binder.as_binder())
diff --git a/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java b/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
index 23d546d..db74358 100644
--- a/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
+++ b/tests/benchmark/src/java/com/android/microdroid/benchmark/MicrodroidBenchmarks.java
@@ -89,7 +89,7 @@
private boolean canBootMicrodroidWithMemory(int mem)
throws VirtualMachineException, InterruptedException, IOException {
VirtualMachineConfig normalConfig = mInner.newVmConfigBuilder()
- .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setPayloadBinaryPath("MicrodroidIdleNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_NONE)
.setMemoryMib(mem)
.build();
@@ -148,7 +148,7 @@
// To grab boot events from log, set debug mode to FULL
VirtualMachineConfig normalConfig = mInner.newVmConfigBuilder()
- .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setPayloadBinaryPath("MicrodroidIdleNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_FULL)
.setMemoryMib(256)
.build();
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 297341b..5c9cf42 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -261,9 +261,10 @@
vm.connectToVsockServer(ITestService.SERVICE_PORT));
vmCdis.cdiAttest = testService.insecurelyExposeAttestationCdi();
vmCdis.instanceSecret = testService.insecurelyExposeVmInstanceSecret();
- forceStop(vm);
} catch (Exception e) {
exception.complete(e);
+ } finally {
+ forceStop(vm);
}
}
};
@@ -280,8 +281,9 @@
public void instancesOfSameVmHaveDifferentCdis() throws Exception {
assumeSupportedKernel();
+ grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig normalConfig = mInner.newVmConfigBuilder()
- .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setPayloadConfigPath("assets/vm_config.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
mInner.forceCreateNewVirtualMachine("test_vm_a", normalConfig);
@@ -304,8 +306,9 @@
public void sameInstanceKeepsSameCdis() throws Exception {
assumeSupportedKernel();
+ grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig normalConfig = mInner.newVmConfigBuilder()
- .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setPayloadConfigPath("assets/vm_config.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
mInner.forceCreateNewVirtualMachine("test_vm", normalConfig);
@@ -326,8 +329,9 @@
public void bccIsSuperficiallyWellFormed() throws Exception {
assumeSupportedKernel();
+ grantPermission(VirtualMachine.USE_CUSTOM_VIRTUAL_MACHINE_PERMISSION);
VirtualMachineConfig normalConfig = mInner.newVmConfigBuilder()
- .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setPayloadConfigPath("assets/vm_config.json")
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = mInner.forceCreateNewVirtualMachine("bcc_vm", normalConfig);
@@ -341,9 +345,10 @@
ITestService testService = ITestService.Stub.asInterface(
vm.connectToVsockServer(ITestService.SERVICE_PORT));
bcc.complete(testService.getBcc());
- forceStop(vm);
} catch (Exception e) {
exception.complete(e);
+ } finally {
+ forceStop(vm);
}
}
};