Merge changes from topic "virtmgr_dir"
* changes:
Rename virtualizationservice files
Move virtmgr files to their own directory
Separate virtualizationservice/manager code into own files
diff --git a/compos/tests/Android.bp b/compos/tests/Android.bp
index 41958ca..511ecd0 100644
--- a/compos/tests/Android.bp
+++ b/compos/tests/Android.bp
@@ -19,7 +19,7 @@
// java_test_host doesn't have data_native_libs but jni_libs can be used to put
// native modules under ./lib directory.
// This works because host tools have rpath (../lib and ./lib).
- data_native_bins: ["bcc_validator"],
+ data_native_bins: ["hwtrust"],
jni_libs: [
"libcrypto",
"libc++",
diff --git a/compos/tests/java/android/compos/test/ComposTestCase.java b/compos/tests/java/android/compos/test/ComposTestCase.java
index d8504f7..fe1c4f0 100644
--- a/compos/tests/java/android/compos/test/ComposTestCase.java
+++ b/compos/tests/java/android/compos/test/ComposTestCase.java
@@ -186,13 +186,16 @@
new FileInputStreamSource(bcc_file));
// Find the validator binary - note that it's specified as a dependency in our Android.bp.
- File validator = getTestInformation().getDependencyFile("bcc_validator", /*targetFirst=*/
- false);
+ File validator = getTestInformation().getDependencyFile("hwtrust", /*targetFirst=*/ false);
- CommandResult result = new RunUtil().runTimedCmd(10000,
- validator.getAbsolutePath(), "verify-chain", bcc_file.getAbsolutePath());
- assertWithMessage("bcc_validator failed").about(command_results())
- .that(result).isSuccess();
+ CommandResult result =
+ new RunUtil()
+ .runTimedCmd(
+ 10000,
+ validator.getAbsolutePath(),
+ "verify-dice-chain",
+ bcc_file.getAbsolutePath());
+ assertWithMessage("hwtrust failed").about(command_results()).that(result).isSuccess();
}
private CommandResult runOdrefresh(CommandRunner android, String command) throws Exception {
diff --git a/pvmfw/avb/tests/api_test.rs b/pvmfw/avb/tests/api_test.rs
index fc6bb1c..872ad63 100644
--- a/pvmfw/avb/tests/api_test.rs
+++ b/pvmfw/avb/tests/api_test.rs
@@ -23,6 +23,7 @@
use std::{
fs,
mem::{size_of, transmute, MaybeUninit},
+ ptr,
};
const MICRODROID_KERNEL_IMG_PATH: &str = "microdroid_kernel";
@@ -205,7 +206,41 @@
)
}
-// TODO(b/256148034): Test that vbmeta with its verification flag overwritten fails verification.
+#[test]
+fn vbmeta_with_verification_flag_disabled_fails_verification() -> Result<()> {
+ // From external/avb/libavb/avb_vbmeta_image.h
+ const AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED: u32 = 2;
+
+ // Arrange.
+ let mut kernel = load_latest_signed_kernel()?;
+ let footer = extract_avb_footer(&kernel)?;
+ let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
+ assert_eq!(
+ 0, vbmeta_header.flags as u32,
+ "The disable flag should not be set in the latest kernel."
+ );
+ let flags_addr = ptr::addr_of!(vbmeta_header.flags) as *const u8;
+ // SAFETY: It is safe as both raw pointers `flags_addr` and `vbmeta_header` are not null.
+ let flags_offset = unsafe { flags_addr.offset_from(ptr::addr_of!(vbmeta_header) as *const u8) };
+ let flags_offset = usize::try_from(footer.vbmeta_offset)? + usize::try_from(flags_offset)?;
+
+ // Act.
+ kernel[flags_offset..(flags_offset + size_of::<u32>())]
+ .copy_from_slice(&AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED.to_be_bytes());
+
+ // Assert.
+ let vbmeta_header = extract_vbmeta_header(&kernel, &footer)?;
+ assert_eq!(
+ AVB_VBMETA_IMAGE_FLAGS_VERIFICATION_DISABLED, vbmeta_header.flags as u32,
+ "VBMeta verification flag should be disabled now."
+ );
+ assert_payload_verification_fails(
+ &kernel,
+ &load_latest_initrd_normal()?,
+ &load_trusted_public_key()?,
+ AvbSlotVerifyError::Verification,
+ )
+}
fn extract_avb_footer(kernel: &[u8]) -> Result<AvbFooter> {
let footer_start = kernel.len() - size_of::<AvbFooter>();
diff --git a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
index e8a36ce..f1da43a 100644
--- a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
+++ b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
@@ -140,12 +140,6 @@
}
}
- protected enum EncryptedStoreOperation {
- NONE,
- READ,
- WRITE,
- }
-
public abstract static class VmEventListener implements VirtualMachineCallback {
private ExecutorService mExecutorService = Executors.newSingleThreadExecutor();
private OptionalLong mVcpuStartedNanoTime = OptionalLong.empty();
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 58e4391..e1a2e40 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -135,7 +135,16 @@
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm", config);
- TestResults testResults = runVmTestService(vm);
+ TestResults testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ tr.mAddInteger = ts.addInteger(123, 456);
+ tr.mAppRunProp = ts.readProperty("debug.microdroid.app.run");
+ tr.mSublibRunProp = ts.readProperty("debug.microdroid.app.sublib.run");
+ tr.mApkContentsPath = ts.getApkContentsPath();
+ tr.mEncryptedStoragePath = ts.getEncryptedStoragePath();
+ });
assertThat(testResults.mException).isNull();
assertThat(testResults.mAddInteger).isEqualTo(123 + 456);
assertThat(testResults.mAppRunProp).isEqualTo("true");
@@ -160,8 +169,14 @@
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm", config);
- TestResults testResults = runVmTestService(vm);
+ TestResults testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ tr.mAddInteger = ts.addInteger(37, 73);
+ });
assertThat(testResults.mException).isNull();
+ assertThat(testResults.mAddInteger).isEqualTo(37 + 73);
}
@Test
@@ -593,7 +608,8 @@
VirtualMachine vm =
forceCreateNewVirtualMachine("test_vm_config_requires_permission", config);
- SecurityException e = assertThrows(SecurityException.class, () -> runVmTestService(vm));
+ SecurityException e =
+ assertThrows(SecurityException.class, () -> runVmTestService(vm, (ts, tr) -> {}));
assertThat(e).hasMessageThat()
.contains("android.permission.USE_CUSTOM_VIRTUAL_MACHINE permission");
}
@@ -642,8 +658,14 @@
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_explicit_apk_path", config);
- TestResults testResults = runVmTestService(vm);
+ TestResults testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ tr.mApkContentsPath = ts.getApkContentsPath();
+ });
assertThat(testResults.mException).isNull();
+ assertThat(testResults.mApkContentsPath).isEqualTo("/mnt/apk");
}
@Test
@@ -671,7 +693,13 @@
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_extra_apk", config);
- TestResults testResults = runVmTestService(vm);
+ TestResults testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ tr.mExtraApkTestProp =
+ ts.readProperty("debug.microdroid.test.extra_apk");
+ });
assertThat(testResults.mExtraApkTestProp).isEqualTo("PASS");
}
@@ -1145,13 +1173,21 @@
newVmConfigBuilder()
.setPayloadBinaryName("MicrodroidTestNativeLib.so")
.setDebugLevel(DEBUG_LEVEL_FULL);
- if (encryptedStoreEnabled) builder = builder.setEncryptedStorageKib(4096);
+ if (encryptedStoreEnabled) {
+ builder.setEncryptedStorageKib(4096);
+ }
VirtualMachineConfig config = builder.build();
String vmNameOrig = "test_vm_orig";
String vmNameImport = "test_vm_import";
VirtualMachine vmOrig = forceCreateNewVirtualMachine(vmNameOrig, config);
// Run something to make the instance.img different with the initialized one.
- TestResults origTestResults = runVmTestService(vmOrig);
+ TestResults origTestResults =
+ runVmTestService(
+ vmOrig,
+ (ts, tr) -> {
+ tr.mAddInteger = ts.addInteger(123, 456);
+ tr.mEncryptedStoragePath = ts.getEncryptedStoragePath();
+ });
assertThat(origTestResults.mException).isNull();
assertThat(origTestResults.mAddInteger).isEqualTo(123 + 456);
VirtualMachineDescriptor descriptor = vmOrig.toDescriptor();
@@ -1172,7 +1208,13 @@
assertThat(vmImport).isNotEqualTo(vmOrig);
vmm.delete(vmNameOrig);
assertThat(vmImport).isEqualTo(vmm.get(vmNameImport));
- TestResults testResults = runVmTestService(vmImport);
+ TestResults testResults =
+ runVmTestService(
+ vmImport,
+ (ts, tr) -> {
+ tr.mAddInteger = ts.addInteger(123, 456);
+ tr.mEncryptedStoragePath = ts.getEncryptedStoragePath();
+ });
assertThat(testResults.mException).isNull();
assertThat(testResults.mAddInteger).isEqualTo(123 + 456);
return testResults;
@@ -1192,7 +1234,12 @@
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm", config);
- TestResults testResults = runVmTestService(vm);
+ TestResults testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ tr.mEncryptedStoragePath = ts.getEncryptedStoragePath();
+ });
assertThat(testResults.mEncryptedStoragePath).isEqualTo("/mnt/encryptedstore");
}
@@ -1209,7 +1256,12 @@
.build();
final VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_caps", vmConfig);
- final TestResults testResults = runVmTestService(vm);
+ final TestResults testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ tr.mEffectiveCapabilities = ts.getEffectiveCapabilities();
+ });
assertThat(testResults.mException).isNull();
assertThat(testResults.mEffectiveCapabilities).isEmpty();
@@ -1228,12 +1280,24 @@
.setDebugLevel(DEBUG_LEVEL_FULL)
.build();
VirtualMachine vm = forceCreateNewVirtualMachine("test_vm_a", config);
- TestResults testResults = runVmTestService(vm, EncryptedStoreOperation.WRITE);
+ TestResults testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ ts.writeToFile(
+ /* content= */ EXAMPLE_STRING,
+ /* path= */ "/mnt/encryptedstore/test_file");
+ });
assertThat(testResults.mException).isNull();
// Re-run the same VM & verify the file persisted. Note, the previous `runVmTestService`
// stopped the VM
- testResults = runVmTestService(vm, EncryptedStoreOperation.READ);
+ testResults =
+ runVmTestService(
+ vm,
+ (ts, tr) -> {
+ tr.mFileContent = ts.readFromFile("/mnt/encryptedstore/test_file");
+ });
assertThat(testResults.mException).isNull();
assertThat(testResults.mFileContent).isEqualTo(EXAMPLE_STRING);
}
@@ -1394,67 +1458,6 @@
String mFileContent;
}
- private TestResults runVmTestService(VirtualMachine vm) throws Exception {
- return runVmTestService(vm, EncryptedStoreOperation.NONE);
- }
-
- private TestResults runVmTestService(VirtualMachine vm, EncryptedStoreOperation mode)
- throws Exception {
- CompletableFuture<Boolean> payloadStarted = new CompletableFuture<>();
- CompletableFuture<Boolean> payloadReady = new CompletableFuture<>();
- TestResults testResults = new TestResults();
- VmEventListener listener =
- new VmEventListener() {
- private void testVMService(VirtualMachine vm) {
- try {
- ITestService testService =
- ITestService.Stub.asInterface(
- vm.connectToVsockServer(ITestService.SERVICE_PORT));
- testResults.mAddInteger = testService.addInteger(123, 456);
- testResults.mAppRunProp =
- testService.readProperty("debug.microdroid.app.run");
- testResults.mSublibRunProp =
- testService.readProperty("debug.microdroid.app.sublib.run");
- testResults.mExtraApkTestProp =
- testService.readProperty("debug.microdroid.test.extra_apk");
- testResults.mApkContentsPath = testService.getApkContentsPath();
- testResults.mEncryptedStoragePath =
- testService.getEncryptedStoragePath();
- testResults.mEffectiveCapabilities =
- testService.getEffectiveCapabilities();
- if (mode == EncryptedStoreOperation.WRITE) {
- testService.writeToFile(
- /*content*/ EXAMPLE_STRING,
- /*path*/ "/mnt/encryptedstore/test_file");
- } else if (mode == EncryptedStoreOperation.READ) {
- testResults.mFileContent =
- testService.readFromFile("/mnt/encryptedstore/test_file");
- }
- } catch (Exception e) {
- testResults.mException = e;
- }
- }
-
- @Override
- public void onPayloadReady(VirtualMachine vm) {
- Log.i(TAG, "onPayloadReady");
- payloadReady.complete(true);
- testVMService(vm);
- forceStop(vm);
- }
-
- @Override
- public void onPayloadStarted(VirtualMachine vm) {
- Log.i(TAG, "onPayloadStarted");
- payloadStarted.complete(true);
- }
- };
- listener.runToFinish(TAG, vm);
- assertThat(payloadStarted.getNow(false)).isTrue();
- assertThat(payloadReady.getNow(false)).isTrue();
- return testResults;
- }
-
private TestResults runVmTestService(VirtualMachine vm, RunTestsAgainstTestService testsToRun)
throws Exception {
CompletableFuture<Boolean> payloadStarted = new CompletableFuture<>();
diff --git a/vm/Android.bp b/vm/Android.bp
index b95dca3..e217786 100644
--- a/vm/Android.bp
+++ b/vm/Android.bp
@@ -14,6 +14,7 @@
"libbinder_rs",
"libclap",
"libenv_logger",
+ "libglob",
"liblibc",
"liblog_rust",
"libmicrodroid_payload_config",
diff --git a/vm/src/run.rs b/vm/src/run.rs
index 6c21dbc..e229933 100644
--- a/vm/src/run.rs
+++ b/vm/src/run.rs
@@ -25,6 +25,7 @@
};
use anyhow::{anyhow, bail, Context, Error};
use binder::ParcelFileDescriptor;
+use glob::glob;
use microdroid_payload_config::VmPayloadConfig;
use rand::{distributions::Alphanumeric, Rng};
use std::fs;
@@ -32,7 +33,6 @@
use std::io;
use std::os::unix::io::{AsRawFd, FromRawFd};
use std::path::{Path, PathBuf};
-use std::process::Command;
use vmclient::{ErrorCode, VmInstance};
use vmconfig::{open_parcel_file, VmConfig};
use zip::ZipArchive;
@@ -147,18 +147,16 @@
run(service, &config, &payload_config_str, console_path, log_path)
}
-const EMPTY_PAYLOAD_APK: &str = "com.android.microdroid.empty_payload";
-
fn find_empty_payload_apk_path() -> Result<PathBuf, Error> {
- let output = Command::new("/system/bin/pm")
- .arg("path")
- .arg(EMPTY_PAYLOAD_APK)
- .output()
- .context("failed to execute pm path")?;
- let output_str = String::from_utf8(output.stdout).context("failed to parse output")?;
- match output_str.strip_prefix("package:") {
- None => Err(anyhow!("Unexpected output {}", output_str)),
- Some(apk_path) => Ok(PathBuf::from(apk_path.trim())),
+ const GLOB_PATTERN: &str = "/apex/com.android.virt/app/**/EmptyPayloadApp.apk";
+ let mut entries: Vec<PathBuf> =
+ glob(GLOB_PATTERN).context("failed to glob")?.filter_map(|e| e.ok()).collect();
+ if entries.len() > 1 {
+ return Err(anyhow!("Found more than one apk matching {}", GLOB_PATTERN));
+ }
+ match entries.pop() {
+ Some(path) => Ok(path),
+ None => Err(anyhow!("No apks match {}", GLOB_PATTERN)),
}
}
@@ -187,9 +185,8 @@
cpus: Option<u32>,
task_profiles: Vec<String>,
) -> Result<(), Error> {
- let apk = find_empty_payload_apk_path()
- .context(anyhow!("failed to find path for {} apk", EMPTY_PAYLOAD_APK))?;
- println!("found path for {} apk: {}", EMPTY_PAYLOAD_APK, apk.display());
+ let apk = find_empty_payload_apk_path()?;
+ println!("found path {}", apk.display());
let work_dir = work_dir.unwrap_or(create_work_dir()?);
let idsig = work_dir.join("apk.idsig");