Merge "Add --prefer-staged to composd_cmd test-compile"
diff --git a/authfs/src/fusefs/mount.rs b/authfs/src/fusefs/mount.rs
index e7f8c94..294c6b1 100644
--- a/authfs/src/fusefs/mount.rs
+++ b/authfs/src/fusefs/mount.rs
@@ -53,8 +53,13 @@
mount_options.push(MountOption::Extra(value));
}
- fuse::mount(mountpoint, "authfs", libc::MS_NOSUID | libc::MS_NODEV, &mount_options)
- .expect("Failed to mount fuse");
+ fuse::mount(
+ mountpoint,
+ "authfs",
+ libc::MS_NOSUID | libc::MS_NODEV | libc::MS_NOEXEC,
+ &mount_options,
+ )
+ .expect("Failed to mount fuse");
fuse::worker::start_message_loop(dev_fuse, MAX_WRITE_BYTES, MAX_READ_BYTES, authfs)
}
diff --git a/compos/verify/verify.rs b/compos/verify/verify.rs
index 55fe1bd..184b9ff 100644
--- a/compos/verify/verify.rs
+++ b/compos/verify/verify.rs
@@ -17,6 +17,7 @@
//! A tool to verify a CompOS signature. It starts a CompOS VM as part of this to retrieve the
//! public key. The tool is intended to be run by odsign during boot.
+use android_logger::LogId;
use anyhow::{bail, Context, Result};
use compos_aidl_interface::binder::ProcessState;
use compos_common::compos_client::{VmInstance, VmParameters};
@@ -39,7 +40,8 @@
android_logger::init_once(
android_logger::Config::default()
.with_tag("compos_verify")
- .with_min_level(log::Level::Info),
+ .with_min_level(log::Level::Info)
+ .with_log_id(LogId::System), // Needed to log successfully early in boot
);
// Redirect panic messages to logcat.
diff --git a/tests/hostside/helper/Android.bp b/tests/hostside/helper/Android.bp
index aa748ab..4ca0bf0 100644
--- a/tests/hostside/helper/Android.bp
+++ b/tests/hostside/helper/Android.bp
@@ -2,12 +2,9 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-java_test_helper_library {
+java_library_host {
name: "VirtualizationTestHelper",
- host_supported: true,
- device_supported: false,
srcs: ["java/**/*.java"],
- test_suites: ["general-tests"],
libs: [
"tradefed",
"compatibility-tradefed",
diff --git a/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java b/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java
index e45e524..0f6204c 100644
--- a/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java
+++ b/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java
@@ -194,6 +194,22 @@
}
}
+ public String getPathForPackage(String packageName)
+ throws DeviceNotAvailableException {
+ return getPathForPackage(getDevice(), packageName);
+ }
+
+ // Get the path to the installed apk. Note that
+ // getDevice().getAppPackageInfo(...).getCodePath() doesn't work due to the incorrect
+ // parsing of the "=" character. (b/190975227). So we use the `pm path` command directly.
+ private static String getPathForPackage(ITestDevice device, String packageName)
+ throws DeviceNotAvailableException {
+ CommandRunner android = new CommandRunner(device);
+ String pathLine = android.run("pm", "path", packageName);
+ assertTrue("package not found", pathLine.startsWith("package:"));
+ return pathLine.substring("package:".length());
+ }
+
public static String startMicrodroid(
ITestDevice androidDevice,
IBuildInfo buildInfo,
@@ -247,13 +263,8 @@
androidDevice.installPackage(apkFile, /* reinstall */ true);
}
- // Get the path to the installed apk. Note that
- // getDevice().getAppPackageInfo(...).getCodePath() doesn't work due to the incorrect
- // parsing of the "=" character. (b/190975227). So we use the `pm path` command directly.
if (apkPath == null) {
- apkPath = android.run("pm", "path", packageName);
- assertTrue(apkPath.startsWith("package:"));
- apkPath = apkPath.substring("package:".length());
+ apkPath = getPathForPackage(androidDevice, packageName);
}
android.run("mkdir", "-p", TEST_ROOT);
diff --git a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
index d0bc91a..e65459a 100644
--- a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
+++ b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
@@ -143,14 +143,6 @@
boolean writable;
}
- private String getPathForPackage(String packageName)
- throws DeviceNotAvailableException {
- CommandRunner android = new CommandRunner(getDevice());
- String pathLine = android.run("pm", "path", packageName);
- assertTrue("package not found", pathLine.startsWith("package:"));
- return pathLine.substring("package:".length());
- }
-
private void resignVirtApex(File virtApexDir, File signingKey) {
File signVirtApex = findTestFile("sign_virt_apex");
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 cd9f284..27e1846 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -73,9 +73,20 @@
private static final String KERNEL_VERSION = SystemProperties.get("ro.kernel.version");
private static class Inner {
+ public boolean mProtectedVm;
public Context mContext;
public VirtualMachineManager mVmm;
public VirtualMachine mVm;
+
+ Inner(boolean protectedVm) {
+ mProtectedVm = protectedVm;
+ }
+
+ /** Create a new VirtualMachineConfig.Builder with the parameterized protection mode. */
+ public VirtualMachineConfig.Builder newVmConfigBuilder(String payloadConfigPath) {
+ return new VirtualMachineConfig.Builder(mContext, payloadConfigPath)
+ .protectedVm(mProtectedVm);
+ }
}
@Parameterized.Parameters(name = "protectedVm={0}")
@@ -112,7 +123,7 @@
.that(HypervisorProperties.hypervisor_vm_supported().orElse(false))
.isTrue();
}
- mInner = new Inner();
+ mInner = new Inner(mProtectedVm);
mInner.mContext = ApplicationProvider.getApplicationContext();
mInner.mVmm = VirtualMachineManager.getInstance(mInner.mContext);
}
@@ -181,8 +192,7 @@
.isNotEqualTo("5.4");
VirtualMachineConfig.Builder builder =
- new VirtualMachineConfig.Builder(mInner.mContext, "assets/vm_config_extra_apk.json")
- .protectedVm(mProtectedVm);
+ mInner.newVmConfigBuilder("assets/vm_config_extra_apk.json");
if (Build.SUPPORTED_ABIS.length > 0) {
String primaryAbi = Build.SUPPORTED_ABIS[0];
switch(primaryAbi) {
@@ -261,9 +271,7 @@
.that(KERNEL_VERSION)
.isNotEqualTo("5.4");
- VirtualMachineConfig.Builder builder =
- new VirtualMachineConfig.Builder(mInner.mContext, "assets/vm_config.json")
- .protectedVm(mProtectedVm);
+ VirtualMachineConfig.Builder builder = mInner.newVmConfigBuilder("assets/vm_config.json");
VirtualMachineConfig normalConfig = builder.debugLevel(DebugLevel.NONE).build();
mInner.mVm = mInner.mVmm.getOrCreate("test_vm", normalConfig);
VmEventListener listener =
@@ -306,10 +314,9 @@
private VmCdis launchVmAndGetCdis(String instanceName)
throws VirtualMachineException, InterruptedException {
- VirtualMachineConfig.Builder builder =
- new VirtualMachineConfig.Builder(mInner.mContext, "assets/vm_config.json")
- .protectedVm(mProtectedVm);
- VirtualMachineConfig normalConfig = builder.debugLevel(DebugLevel.NONE).build();
+ VirtualMachineConfig normalConfig = mInner.newVmConfigBuilder("assets/vm_config.json")
+ .debugLevel(DebugLevel.NONE)
+ .build();
mInner.mVm = mInner.mVmm.getOrCreate(instanceName, normalConfig);
final VmCdis vmCdis = new VmCdis();
final CompletableFuture<Exception> exception = new CompletableFuture<>();
@@ -391,10 +398,9 @@
.that(KERNEL_VERSION)
.isNotEqualTo("5.4");
- VirtualMachineConfig.Builder builder =
- new VirtualMachineConfig.Builder(mInner.mContext, "assets/vm_config.json")
- .protectedVm(mProtectedVm);
- VirtualMachineConfig normalConfig = builder.debugLevel(DebugLevel.NONE).build();
+ VirtualMachineConfig normalConfig = mInner.newVmConfigBuilder("assets/vm_config.json")
+ .debugLevel(DebugLevel.NONE)
+ .build();
mInner.mVm = mInner.mVmm.getOrCreate("bcc_vm", normalConfig);
final VmCdis vmCdis = new VmCdis();
final CompletableFuture<byte[]> bcc = new CompletableFuture<>();
@@ -433,6 +439,10 @@
private static final UUID MICRODROID_PARTITION_UUID =
UUID.fromString("cf9afe9a-0662-11ec-a329-c32663a09d75");
+ private static final UUID U_BOOT_AVB_PARTITION_UUID =
+ UUID.fromString("7e8221e7-03e6-4969-948b-73a4c809a4f2");
+ private static final UUID U_BOOT_ENV_PARTITION_UUID =
+ UUID.fromString("0ab72d30-86ae-4d05-81b2-c1760be2b1f9");
private static final long BLOCK_SIZE = 512;
// Find the starting offset which holds the data of a partition having UUID.
@@ -460,53 +470,11 @@
file.writeByte(b ^ 1);
}
- @Test
- public void bootFailsWhenInstanceDiskIsCompromised()
- throws VirtualMachineException, InterruptedException, IOException {
- assume().withMessage("Skip on Cuttlefish. b/195765441")
- .that(android.os.Build.DEVICE)
- .isNotEqualTo("vsoc_x86_64");
-
- VirtualMachineConfig config =
- new VirtualMachineConfig.Builder(mInner.mContext, "assets/vm_config.json")
- .protectedVm(mProtectedVm)
- .debugLevel(DebugLevel.NONE)
- .build();
-
- // Remove any existing VM so we can start from scratch
- VirtualMachine oldVm = mInner.mVmm.getOrCreate("test_vm_integrity", config);
- oldVm.delete();
-
- mInner.mVm = mInner.mVmm.getOrCreate("test_vm_integrity", config);
-
- final CompletableFuture<Boolean> payloadReady = new CompletableFuture<>();
- VmEventListener listener =
- new VmEventListener() {
- @Override
- public void onPayloadReady(VirtualMachine vm) {
- payloadReady.complete(true);
- forceStop(vm);
- }
- };
- listener.runToFinish(mInner.mVm);
- assertThat(payloadReady.getNow(false)).isTrue();
-
- // Launch the same VM after flipping a bit of the instance image.
- // Flip actual data, as flipping trivial bits like the magic string isn't interesting.
- File vmRoot = new File(mInner.mContext.getFilesDir(), "vm");
- File vmDir = new File(vmRoot, "test_vm_integrity");
- File instanceImgPath = new File(vmDir, "instance.img");
- RandomAccessFile instanceFile = new RandomAccessFile(instanceImgPath, "rw");
-
- // microdroid data partition must exist.
- OptionalLong microdroidPartitionOffset =
- findPartitionDataOffset(instanceFile, MICRODROID_PARTITION_UUID);
- assertThat(microdroidPartitionOffset.isPresent()).isTrue();
-
- flipBit(instanceFile, microdroidPartitionOffset.getAsLong());
- mInner.mVm = mInner.mVmm.get("test_vm_integrity"); // re-load the vm with new instance disk
+ private boolean tryBootVm(String vmName)
+ throws VirtualMachineException, InterruptedException {
+ mInner.mVm = mInner.mVmm.get(vmName); // re-load the vm before running tests
final CompletableFuture<Boolean> payloadStarted = new CompletableFuture<>();
- listener =
+ VmEventListener listener =
new VmEventListener() {
@Override
public void onPayloadStarted(VirtualMachine vm, ParcelFileDescriptor stream) {
@@ -515,7 +483,45 @@
}
};
listener.runToFinish(mInner.mVm);
- assertThat(payloadStarted.getNow(false)).isFalse();
- flipBit(instanceFile, microdroidPartitionOffset.getAsLong());
+ return payloadStarted.getNow(false);
+ }
+
+ @Test
+ public void bootFailsWhenInstanceDiskIsCompromised()
+ throws VirtualMachineException, InterruptedException, IOException {
+ assume().withMessage("Skip on Cuttlefish. b/195765441")
+ .that(android.os.Build.DEVICE)
+ .isNotEqualTo("vsoc_x86_64");
+
+ VirtualMachineConfig config = mInner.newVmConfigBuilder("assets/vm_config.json")
+ .debugLevel(DebugLevel.NONE)
+ .build();
+
+ // Remove any existing VM so we can start from scratch
+ VirtualMachine oldVm = mInner.mVmm.getOrCreate("test_vm_integrity", config);
+ oldVm.delete();
+ mInner.mVmm.getOrCreate("test_vm_integrity", config);
+
+ assertThat(tryBootVm("test_vm_integrity")).isTrue();
+
+ // Launch the same VM after flipping a bit of the instance image.
+ // Flip actual data, as flipping trivial bits like the magic string isn't interesting.
+ File vmRoot = new File(mInner.mContext.getFilesDir(), "vm");
+ File vmDir = new File(vmRoot, "test_vm_integrity");
+ File instanceImgPath = new File(vmDir, "instance.img");
+ RandomAccessFile instanceFile = new RandomAccessFile(instanceImgPath, "rw");
+
+ // partitions may or may not exist
+ for (UUID uuid :
+ new UUID[] {
+ MICRODROID_PARTITION_UUID, U_BOOT_AVB_PARTITION_UUID, U_BOOT_ENV_PARTITION_UUID
+ }) {
+ OptionalLong offset = findPartitionDataOffset(instanceFile, uuid);
+ if (!offset.isPresent()) continue;
+
+ flipBit(instanceFile, offset.getAsLong());
+ assertThat(tryBootVm("test_vm_integrity")).isFalse();
+ flipBit(instanceFile, offset.getAsLong());
+ }
}
}