Merge changes Ib977d21a,I9daaa3bb
* changes:
Update kernel to builds 9223523
Update kernel to builds 9223523
diff --git a/microdroid/vm_payload/Android.bp b/microdroid/vm_payload/Android.bp
index dc314ce..eeca1c1 100644
--- a/microdroid/vm_payload/Android.bp
+++ b/microdroid/vm_payload/Android.bp
@@ -13,6 +13,7 @@
"libandroid_logger",
"libanyhow",
"libbinder_rs",
+ "liblazy_static",
"liblog_rust",
"librpcbinder_rs",
],
diff --git a/microdroid/vm_payload/include/vm_payload.h b/microdroid/vm_payload/include/vm_payload.h
index dc01662..2aeb44e 100644
--- a/microdroid/vm_payload/include/vm_payload.h
+++ b/microdroid/vm_payload/include/vm_payload.h
@@ -96,6 +96,17 @@
*/
bool AVmPayload_getDiceAttestationCdi(void *data, size_t size, size_t *total);
+/**
+ * Gets the path to the APK contents. It is a directory, under which are
+ * the unzipped contents of the APK containing the payload, all read-only
+ * but accessible to the payload.
+ *
+ * \return the path to the APK contents. The returned string should not be
+ * deleted or freed by the application. The string remains valid for the
+ * lifetime of the VM.
+ */
+const char *AVmPayload_getApkContentsPath(void);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/microdroid/vm_payload/src/vm_payload_service.rs b/microdroid/vm_payload/src/vm_payload_service.rs
index bec4fde..b0dd891 100644
--- a/microdroid/vm_payload/src/vm_payload_service.rs
+++ b/microdroid/vm_payload/src/vm_payload_service.rs
@@ -15,12 +15,19 @@
//! This module handles the interaction with virtual machine payload service.
use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
- IVmPayloadService, VM_PAYLOAD_SERVICE_NAME};
+ IVmPayloadService, VM_PAYLOAD_SERVICE_NAME, VM_APK_CONTENTS_PATH};
use anyhow::{Context, Result};
use binder::{wait_for_interface, Strong, unstable_api::{AIBinder, new_spibinder}};
+use lazy_static::lazy_static;
use log::{error, info, Level};
use rpcbinder::run_vsock_rpc_server;
-use std::os::raw::c_void;
+use std::ffi::CString;
+use std::os::raw::{c_char, c_void};
+
+lazy_static! {
+ static ref VM_APK_CONTENTS_PATH_C: CString =
+ CString::new(VM_APK_CONTENTS_PATH).expect("CString::new failed");
+}
/// Notifies the host that the payload is ready.
/// Returns true if the notification succeeds else false.
@@ -185,6 +192,12 @@
}
}
+/// Gets the path to the APK contents.
+#[no_mangle]
+pub extern "C" fn AVmPayload_getApkContentsPath() -> *const c_char {
+ (*VM_APK_CONTENTS_PATH_C).as_ptr()
+}
+
fn try_get_dice_attestation_cdi() -> Result<Vec<u8>> {
get_vm_payload_service()?.getDiceAttestationCdi().context("Cannot get attestation CDI")
}
diff --git a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
index 4dd3db6..4823bb8 100644
--- a/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
+++ b/microdroid_manager/aidl/android/system/virtualization/payload/IVmPayloadService.aidl
@@ -24,6 +24,9 @@
/** Name of the service IVmPayloadService. */
const String VM_PAYLOAD_SERVICE_NAME = "virtual_machine_payload_service";
+ /** Path to the APK contents path. */
+ const String VM_APK_CONTENTS_PATH = "/mnt/apk";
+
/** Notifies that the payload is ready to serve. */
void notifyPayloadReady();
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index e42f159..b8e85e7 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -33,6 +33,7 @@
VirtualMachineCpuStatus::VirtualMachineCpuStatus,
VirtualMachineMemStatus::VirtualMachineMemStatus,
};
+use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::VM_APK_CONTENTS_PATH;
use anyhow::{anyhow, bail, ensure, Context, Error, Result};
use apkverify::{get_public_key_der, verify, V4Signature};
use binder::{ProcessState, Strong};
@@ -398,7 +399,7 @@
MountForExec::Allowed,
"fscontext=u:object_r:zipfusefs:s0,context=u:object_r:system_file:s0",
Path::new("/dev/block/mapper/microdroid-apk"),
- Path::new("/mnt/apk"),
+ Path::new(VM_APK_CONTENTS_PATH),
Some(APK_MOUNT_DONE_PROP),
)
.context("Failed to run zipfuse")?;
@@ -824,7 +825,7 @@
let mut watcher = PropertyWatcher::new("ro.product.cpu.abilist")?;
let value = watcher.read(|_name, value| Ok(value.trim().to_string()))?;
let abi = value.split(',').next().ok_or_else(|| anyhow!("no abilist"))?;
- let path = format!("/mnt/apk/lib/{}/{}", abi, name);
+ let path = format!("{}/lib/{}/{}", VM_APK_CONTENTS_PATH, abi, name);
let metadata = fs::metadata(&path).with_context(|| format!("Unable to access {}", path))?;
if !metadata.is_file() {
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index d0fc9a9..b644905 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -10,6 +10,7 @@
edition: "2021",
rustlibs: [
"liblog_rust_nostd",
+ "libpvmfw_embedded_key",
"libvmbase",
],
apex_available: ["com.android.virt"],
@@ -44,6 +45,34 @@
}
prebuilt_etc {
+ name: "pvmfw_embedded_key",
+ src: ":avb_testkey_rsa4096_pub_bin",
+ installable: false,
+}
+
+genrule {
+ name: "pvmfw_embedded_key_rs",
+ srcs: [":pvmfw_embedded_key"],
+ out: ["lib.rs"],
+ cmd: "(" +
+ " echo '#![no_std]';" +
+ " echo '#![allow(missing_docs)]';" +
+ " echo 'pub const PUBLIC_KEY: &[u8] = &[';" +
+ " xxd -i < $(in);" +
+ " echo '];';" +
+ ") > $(out)",
+}
+
+rust_library_rlib {
+ name: "libpvmfw_embedded_key",
+ defaults: ["vmbase_ffi_defaults"],
+ prefer_rlib: true,
+ srcs: [":pvmfw_embedded_key_rs"],
+ crate_name: "pvmfw_embedded_key",
+ apex_available: ["com.android.virt"],
+}
+
+prebuilt_etc {
name: "pvmfw_sign_key",
src: ":avb_testkey_rsa4096",
installable: false,
diff --git a/pvmfw/src/avb.rs b/pvmfw/src/avb.rs
new file mode 100644
index 0000000..1abe73f
--- /dev/null
+++ b/pvmfw/src/avb.rs
@@ -0,0 +1,17 @@
+// Copyright 2022, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Image verification.
+
+pub use pvmfw_embedded_key::PUBLIC_KEY;
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index 9f8cbd2..870172d 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -17,12 +17,14 @@
#![no_main]
#![no_std]
+mod avb;
mod entry;
mod exceptions;
mod helpers;
mod mmio_guard;
mod smccc;
+use avb::PUBLIC_KEY;
use log::{debug, info};
fn main(fdt: &mut [u8], payload: &[u8]) {
@@ -33,6 +35,6 @@
payload.as_ptr() as usize,
payload.len(),
);
-
+ debug!("AVB public key: addr={:?}, size={:#x} ({1})", PUBLIC_KEY.as_ptr(), PUBLIC_KEY.len());
info!("Starting payload...");
}
diff --git a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
index ebb2bcf..e8c435f 100644
--- a/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
+++ b/tests/aidl/com/android/microdroid/testservice/ITestService.aidl
@@ -33,4 +33,7 @@
/* get the VM's boot certificate chain (BCC). */
byte[] getBcc();
+
+ /* get the APK contents path. */
+ String getApkContentsPath();
}
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 5c9cf42..c4296df 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -111,6 +111,7 @@
assertThat(testResults.mAddInteger).isEqualTo(123 + 456);
assertThat(testResults.mAppRunProp).isEqualTo("true");
assertThat(testResults.mSublibRunProp).isEqualTo("true");
+ assertThat(testResults.mApkContentsPath).isEqualTo("/mnt/apk");
}
@Test
@@ -538,6 +539,7 @@
String mAppRunProp;
String mSublibRunProp;
String mExtraApkTestProp;
+ String mApkContentsPath;
}
private TestResults runVmTestService(VirtualMachine vm) throws Exception {
@@ -557,6 +559,7 @@
testService.readProperty("debug.microdroid.app.sublib.run");
testResults.mExtraApkTestProp =
testService.readProperty("debug.microdroid.test.extra_apk");
+ testResults.mApkContentsPath = testService.getApkContentsPath();
} catch (Exception e) {
testResults.mException = e;
}
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index d57d224..1a3e940 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -112,6 +112,17 @@
}
return ndk::ScopedAStatus::ok();
}
+
+ ndk::ScopedAStatus getApkContentsPath(std::string* out) override {
+ const char* path_c = AVmPayload_getApkContentsPath();
+ if (path_c == nullptr) {
+ return ndk::ScopedAStatus::
+ fromServiceSpecificErrorWithMessage(0, "Failed to get APK contents path");
+ }
+ std::string path(path_c);
+ *out = path;
+ return ndk::ScopedAStatus::ok();
+ }
};
auto testService = ndk::SharedRefBase::make<TestService>();
diff --git a/vmbase/common.h b/vmbase/common.h
new file mode 100644
index 0000000..788dcf0
--- /dev/null
+++ b/vmbase/common.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#define PSCI_SYSTEM_RESET (0x84000009)
+
+.macro adr_l, reg:req, sym:req
+ adrp \reg, \sym
+ add \reg, \reg, :lo12:\sym
+.endm
+
+.macro mov_i, reg:req, imm:req
+ movz \reg, :abs_g3:\imm
+ movk \reg, :abs_g2_nc:\imm
+ movk \reg, :abs_g1_nc:\imm
+ movk \reg, :abs_g0_nc:\imm
+.endm
+
+.macro reset_or_hang
+ mov_i x0, PSCI_SYSTEM_RESET
+ hvc 0
+999: wfi
+ b 999b
+.endm
diff --git a/vmbase/entry.S b/vmbase/entry.S
index 75ab90b..5f0a2ce 100644
--- a/vmbase/entry.S
+++ b/vmbase/entry.S
@@ -14,17 +14,7 @@
* limitations under the License.
*/
-.macro adr_l, reg:req, sym:req
- adrp \reg, \sym
- add \reg, \reg, :lo12:\sym
-.endm
-
-.macro mov_i, reg:req, imm:req
- movz \reg, :abs_g3:\imm
- movk \reg, :abs_g2_nc:\imm
- movk \reg, :abs_g1_nc:\imm
- movk \reg, :abs_g0_nc:\imm
-.endm
+#include <common.h>
.set .L_MAIR_DEV_nGnRE, 0x04
.set .L_MAIR_MEM_WBWA, 0xff
@@ -95,6 +85,16 @@
adr x30, vector_table_panic
msr vbar_el1, x30
+ /*
+ * Our load address is set by the host so validate it before proceeding.
+ */
+ adr x30, entry
+ mov_i x29, entry
+ cmp x29, x30
+ b.eq 1f
+ reset_or_hang
+1:
+
adrp x30, idmap
msr ttbr0_el1, x30
diff --git a/vmbase/exceptions_panic.S b/vmbase/exceptions_panic.S
index 4a3f2db..54735b2 100644
--- a/vmbase/exceptions_panic.S
+++ b/vmbase/exceptions_panic.S
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <common.h>
+
/**
* The following table is intended to trap any fault resulting from the very
* first memory accesses. They assume that PSCI v0.2 is available and provides
@@ -21,80 +23,69 @@
* results in the core busy-looping.
*/
-.macro exception_panic
- mov x0, 0x84000000
- movk x0, 9
- mov x1, 0
- mov x2, 0
- mov x3, 0
- hvc 0
-0: wfi
- b 0b
-.endm
-
.section .text.vector_table_panic, "ax"
.global vector_table_panic
.balign 0x800
vector_table_panic:
sync_cur_sp0_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
irq_cur_sp0_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
fiq_cur_sp0_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
serr_cur_sp0_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
sync_cur_spx_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
irq_cur_spx_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
fiq_cur_spx_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
serr_cur_spx_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
sync_lower_64_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
irq_lower_64_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
fiq_lower_64_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
serr_lower_64_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
sync_lower_32_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
irq_lower_32_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
fiq_lower_32_panic:
- exception_panic
+ reset_or_hang
.balign 0x80
serr_lower_32_panic:
- exception_panic
+ reset_or_hang