Merge "Changes for rust 1.72" into main
diff --git a/OWNERS b/OWNERS
index 310add7..e560cec 100644
--- a/OWNERS
+++ b/OWNERS
@@ -12,16 +12,19 @@
# Other owners
alanstokes@google.com
aliceywang@google.com
-ardb@google.com
-ascull@google.com
inseob@google.com
+jaewan@google.com
+jakobvukalovic@google.com
jeffv@google.com
jooyung@google.com
-mzyngier@google.com
+keirf@google.com
ptosi@google.com
qperret@google.com
qwandor@google.com
-serbanc@google.com
+sebastianene@google.com
+seungjaeyoo@google.com
shikhapanwar@google.com
+smostafa@google.com
tabba@google.com
+vdonnefort@google.com
victorhsieh@google.com
diff --git a/apex/virtualizationservice.rc b/apex/virtualizationservice.rc
index be90904..8283594 100644
--- a/apex/virtualizationservice.rc
+++ b/apex/virtualizationservice.rc
@@ -22,7 +22,7 @@
service vfio_handler /apex/com.android.virt/bin/vfio_handler
user root
- group root
+ group system
interface aidl android.system.virtualizationservice_internal.IVfioHandler
disabled
oneshot
diff --git a/compos/tests/java/android/compos/test/ComposTestCase.java b/compos/tests/java/android/compos/test/ComposTestCase.java
index 244d34e..4851321 100644
--- a/compos/tests/java/android/compos/test/ComposTestCase.java
+++ b/compos/tests/java/android/compos/test/ComposTestCase.java
@@ -192,7 +192,7 @@
.runTimedCmd(
10000,
validator.getAbsolutePath(),
- "verify-dice-chain",
+ "dice-chain",
bcc_file.getAbsolutePath());
assertWithMessage("hwtrust failed").about(command_results()).that(result).isSuccess();
}
diff --git a/docs/getting_started.md b/docs/getting_started.md
index d970c12..74f2012 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -99,7 +99,7 @@
payload using the following command:
```shell
-package/modules/Virtualization/vm/vm_shell.sh start-microdroid --auto-connect -- --protected
+packages/modules/Virtualization/vm/vm_shell.sh start-microdroid --auto-connect -- --protected
```
You will see the log messages like the below.
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index afc36d0..a305e03 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -16,8 +16,6 @@
//! to a bare-metal environment.
#![no_std]
-#![deny(unsafe_op_in_unsafe_fn)]
-#![deny(clippy::undocumented_unsafe_blocks)]
mod iterators;
diff --git a/pvmfw/Android.bp b/pvmfw/Android.bp
index bbe00b5..1aa5935 100644
--- a/pvmfw/Android.bp
+++ b/pvmfw/Android.bp
@@ -7,8 +7,6 @@
crate_name: "pvmfw",
defaults: ["vmbase_ffi_defaults"],
srcs: ["src/main.rs"],
- // Require unsafe blocks for inside unsafe functions.
- flags: ["-Dunsafe_op_in_unsafe_fn"],
features: [
"legacy",
],
diff --git a/pvmfw/avb/Android.bp b/pvmfw/avb/Android.bp
index 49c4717..4efee6a 100644
--- a/pvmfw/avb/Android.bp
+++ b/pvmfw/avb/Android.bp
@@ -7,8 +7,6 @@
crate_name: "pvmfw_avb",
srcs: ["src/lib.rs"],
prefer_rlib: true,
- // Require unsafe blocks for inside unsafe functions.
- flags: ["-Dunsafe_op_in_unsafe_fn"],
rustlibs: [
"libavb_bindgen_nostd",
"libtinyvec_nostd",
diff --git a/pvmfw/src/dice.rs b/pvmfw/src/dice.rs
index 28271d3..9542429 100644
--- a/pvmfw/src/dice.rs
+++ b/pvmfw/src/dice.rs
@@ -18,8 +18,8 @@
use core::mem::size_of;
use core::slice;
use diced_open_dice::{
- bcc_format_config_descriptor, bcc_handover_main_flow, hash, Config, DiceMode, Hash,
- InputValues, HIDDEN_SIZE,
+ bcc_format_config_descriptor, bcc_handover_main_flow, hash, Config, DiceConfigValues, DiceMode,
+ Hash, InputValues, HIDDEN_SIZE,
};
use pvmfw_avb::{DebugLevel, Digest, VerifiedBootData};
use vmbase::cstr;
@@ -63,12 +63,10 @@
next_bcc: &mut [u8],
) -> diced_open_dice::Result<()> {
let mut config_descriptor_buffer = [0; 128];
- let config_descriptor_size = bcc_format_config_descriptor(
- Some(cstr!("vm_entry")),
- None, // component_version
- false, // resettable
- &mut config_descriptor_buffer,
- )?;
+ let config_values =
+ DiceConfigValues { component_name: Some(cstr!("vm_entry")), ..Default::default() };
+ let config_descriptor_size =
+ bcc_format_config_descriptor(&config_values, &mut config_descriptor_buffer)?;
let config = &config_descriptor_buffer[..config_descriptor_size];
let dice_inputs = InputValues::new(
diff --git a/pvmfw/src/memory.rs b/pvmfw/src/memory.rs
index 27ab719..06158dd 100644
--- a/pvmfw/src/memory.rs
+++ b/pvmfw/src/memory.rs
@@ -14,8 +14,6 @@
//! Low-level allocation and tracking of main memory.
-#![deny(unsafe_op_in_unsafe_fn)]
-
use crate::helpers::PVMFW_PAGE_SIZE;
use aarch64_paging::paging::VirtualAddress;
use aarch64_paging::MapError;
diff --git a/tests/testapk/Android.bp b/tests/testapk/Android.bp
index 8a31c21..526f240 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -2,6 +2,17 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
+android_app_certificate {
+ name: "MicrodroidTestAppCert",
+
+ // The default app cert is the same as the default platform cert
+ // (on a test-keys build), which means we end up getting assigned
+ // the permissions via signature and can't reliably disclaim
+ // them. So instead we use our own custom cert. See b/290582742.
+ // Created via: development/tools/make_key microdroid_test_app '/CN=microdroid_test_app'
+ certificate: "microdroid_test_app",
+}
+
java_defaults {
name: "MicrodroidTestAppsDefaults",
test_suites: [
@@ -12,6 +23,7 @@
"com.android.microdroid.testservice-java",
"com.android.microdroid.test.vmshare_service-java",
],
+ certificate: ":MicrodroidTestAppCert",
sdk_version: "test_current",
jni_uses_platform_apis: true,
use_embedded_native_libs: true,
diff --git a/tests/testapk/microdroid_test_app.pk8 b/tests/testapk/microdroid_test_app.pk8
new file mode 100644
index 0000000..dc012bd
--- /dev/null
+++ b/tests/testapk/microdroid_test_app.pk8
Binary files differ
diff --git a/tests/testapk/microdroid_test_app.x509.pem b/tests/testapk/microdroid_test_app.x509.pem
new file mode 100644
index 0000000..9a0309c
--- /dev/null
+++ b/tests/testapk/microdroid_test_app.x509.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDHzCCAgegAwIBAgIUNnOI4tOMieX67OtyD+6BjTsLm0IwDQYJKoZIhvcNAQEL
+BQAwHjEcMBoGA1UEAwwTbWljcm9kcm9pZF90ZXN0X2FwcDAgFw0yMzA4MTgxNDA4
+MDZaGA8yMDUxMDEwMzE0MDgwNlowHjEcMBoGA1UEAwwTbWljcm9kcm9pZF90ZXN0
+X2FwcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK7B9xDTD2kS4xFQ
+gwQThRqnxKzOmckYqv2XznXq7tCuhU+RgXDrub7Aiq+QgA25Ouw8ORM5FkZAxD6j
+hCRSVo8cyXdNfPygRY/56umL6KqLMqB0tXLHPst3Lh8fl2su2S+jWL71lUwdOBmu
+nBIa1UqxI9PChR/uIqGyDxNRlUnqOA5/FgyX95P9wj8zmXEFe5No8rL/9hjpBvw1
+cOJCH4hea6JKDA15XYxDaTyj5pkmGb228ZbQb10XwOIhtS94CVxIvqmREzZHL7b0
+cjzCwFDDF6sQoVDi71eFYSWInxSNErDU6wv5h2t6+PV+9mGwTi/AJuxTmevSUoAp
+tGwq0NMCAwEAAaNTMFEwHQYDVR0OBBYEFI2m/0SoaNew99YPQlo6oYPJfh7lMB8G
+A1UdIwQYMBaAFI2m/0SoaNew99YPQlo6oYPJfh7lMA8GA1UdEwEB/wQFMAMBAf8w
+DQYJKoZIhvcNAQELBQADggEBABxIQ66ACIrSnDCiI/DqdPPwHf4vva2Y0bVJ5tXN
+ufFQN0Hr4UnttDzWPtfZHQTnrA478b9Z/g4Y0qg/tj2g5oZP50coF9a39mPe6v2k
+vazkMp2H/+ilG4c8L6QsC7UKXn7Lxxznn3ijlh1lYVJ3E6nMibGRKrfaVFpEwtvy
+zT0K8eK9KUZIyG5nf1v8On4Vfu7MnavuxNubKoUhfu0B8hSd5JKiGDuUkSk3MiFX
+uctYmJZEUD1xLI787SzqrhuYMGfuwmrrI0N46yvUgRgxpkVj2s6GNWqRD3F/fOG+
+qFbeenHjFoMJN9HIAZaz4OqzgGfhfMf596rn+HPAJnRMtsI=
+-----END CERTIFICATE-----
diff --git a/tests/testapk/test.keystore b/tests/testapk/test.keystore
deleted file mode 100644
index 2946641..0000000
--- a/tests/testapk/test.keystore
+++ /dev/null
Binary files differ
diff --git a/virtualizationservice/vfio_handler/Android.bp b/virtualizationservice/vfio_handler/Android.bp
index 9ed17f2..66662d5 100644
--- a/virtualizationservice/vfio_handler/Android.bp
+++ b/virtualizationservice/vfio_handler/Android.bp
@@ -27,6 +27,8 @@
"liblazy_static",
"liblog_rust",
"libnix",
+ "librustutils",
+ "libzerocopy",
],
apex_available: ["com.android.virt"],
}
diff --git a/virtualizationservice/vfio_handler/src/aidl.rs b/virtualizationservice/vfio_handler/src/aidl.rs
index a826c75..bb9faf1 100644
--- a/virtualizationservice/vfio_handler/src/aidl.rs
+++ b/virtualizationservice/vfio_handler/src/aidl.rs
@@ -19,9 +19,15 @@
use android_system_virtualizationservice_internal::binder::ParcelFileDescriptor;
use binder::{self, ExceptionCode, Interface, IntoBinderResult};
use lazy_static::lazy_static;
-use std::fs::{read_link, write};
-use std::io::Write;
-use std::path::Path;
+use std::fs::{read_link, write, File};
+use std::io::{Read, Seek, SeekFrom, Write};
+use std::mem::size_of;
+use std::path::{Path, PathBuf};
+use rustutils::system_properties;
+use zerocopy::{
+ byteorder::{BigEndian, U32},
+ FromBytes,
+};
#[derive(Debug, Default)]
pub struct VfioHandler {}
@@ -45,18 +51,10 @@
return Err(anyhow!("VFIO-platform not supported"))
.or_binder_exception(ExceptionCode::UNSUPPORTED_OPERATION);
}
-
devices.iter().try_for_each(|x| bind_device(Path::new(x)))?;
- let mut dtbo = dtbo
- .as_ref()
- .try_clone()
- .context("Failed to clone File from ParcelFileDescriptor")
- .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?;
- // TODO(b/291191362): write DTBO for devices to dtbo.
- dtbo.write(b"\n")
- .context("Can't write to ParcelFileDescriptor")
- .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?;
+ write_dtbo(dtbo)?;
+
Ok(())
}
}
@@ -65,13 +63,52 @@
const SYSFS_PLATFORM_DEVICES_PATH: &str = "/sys/devices/platform/";
const VFIO_PLATFORM_DRIVER_PATH: &str = "/sys/bus/platform/drivers/vfio-platform";
const SYSFS_PLATFORM_DRIVERS_PROBE_PATH: &str = "/sys/bus/platform/drivers_probe";
+const DT_TABLE_MAGIC: u32 = 0xd7b7ab1e;
-lazy_static! {
- static ref IS_VFIO_SUPPORTED: bool = is_vfio_supported();
+/// The structure of DT table header in dtbo.img.
+/// https://source.android.com/docs/core/architecture/dto/partitions
+#[repr(C)]
+#[derive(Debug, FromBytes)]
+struct DtTableHeader {
+ /// DT_TABLE_MAGIC
+ magic: U32<BigEndian>,
+ /// includes dt_table_header + all dt_table_entry and all dtb/dtbo
+ _total_size: U32<BigEndian>,
+ /// sizeof(dt_table_header)
+ header_size: U32<BigEndian>,
+ /// sizeof(dt_table_entry)
+ dt_entry_size: U32<BigEndian>,
+ /// number of dt_table_entry
+ dt_entry_count: U32<BigEndian>,
+ /// offset to the first dt_table_entry from head of dt_table_header
+ dt_entries_offset: U32<BigEndian>,
+ /// flash page size we assume
+ _page_size: U32<BigEndian>,
+ /// DTBO image version, the current version is 0. The version will be
+ /// incremented when the dt_table_header struct is updated.
+ _version: U32<BigEndian>,
}
-fn is_vfio_supported() -> bool {
- Path::new(DEV_VFIO_PATH).exists() && Path::new(VFIO_PLATFORM_DRIVER_PATH).exists()
+/// The structure of each DT table entry (v0) in dtbo.img.
+/// https://source.android.com/docs/core/architecture/dto/partitions
+#[repr(C)]
+#[derive(Debug, FromBytes)]
+struct DtTableEntry {
+ /// size of each DT
+ dt_size: U32<BigEndian>,
+ /// offset from head of dt_table_header
+ dt_offset: U32<BigEndian>,
+ /// optional, must be zero if unused
+ _id: U32<BigEndian>,
+ /// optional, must be zero if unused
+ _rev: U32<BigEndian>,
+ /// optional, must be zero if unused
+ _custom: [U32<BigEndian>; 4],
+}
+
+lazy_static! {
+ static ref IS_VFIO_SUPPORTED: bool =
+ Path::new(DEV_VFIO_PATH).exists() && Path::new(VFIO_PLATFORM_DRIVER_PATH).exists();
}
fn check_platform_device(path: &Path) -> binder::Result<()> {
@@ -158,3 +195,109 @@
check_platform_device(&path)?;
bind_vfio_driver(&path)
}
+
+fn get_dtbo_img_path() -> binder::Result<PathBuf> {
+ let slot_suffix = system_properties::read("ro.boot.slot_suffix")
+ .context("Failed to read ro.boot.slot_suffix")
+ .or_service_specific_exception(-1)?
+ .ok_or_else(|| anyhow!("slot_suffix is none"))
+ .or_service_specific_exception(-1)?;
+ Ok(PathBuf::from(format!("/dev/block/by-name/dtbo{slot_suffix}")))
+}
+
+fn read_values(file: &mut File, size: usize, offset: u64) -> binder::Result<Vec<u8>> {
+ file.seek(SeekFrom::Start(offset))
+ .context("Cannot seek the offset")
+ .or_service_specific_exception(-1)?;
+ let mut buffer = vec![0_u8; size];
+ file.read_exact(&mut buffer)
+ .context("Failed to read buffer")
+ .or_service_specific_exception(-1)?;
+ Ok(buffer)
+}
+
+fn get_dt_table_header(file: &mut File) -> binder::Result<DtTableHeader> {
+ let values = read_values(file, size_of::<DtTableHeader>(), 0)?;
+ let dt_table_header = DtTableHeader::read_from(values.as_slice())
+ .context("DtTableHeader is invalid")
+ .or_service_specific_exception(-1)?;
+ if dt_table_header.magic.get() != DT_TABLE_MAGIC
+ || dt_table_header.header_size.get() as usize != size_of::<DtTableHeader>()
+ {
+ return Err(anyhow!("DtTableHeader is invalid")).or_service_specific_exception(-1)?;
+ }
+ Ok(dt_table_header)
+}
+
+fn get_dt_table_entry(
+ file: &mut File,
+ header: &DtTableHeader,
+ index: u32,
+) -> binder::Result<DtTableEntry> {
+ if index >= header.dt_entry_count.get() {
+ return Err(anyhow!("Invalid dtbo index {index}")).or_service_specific_exception(-1)?;
+ }
+ let Some(prev_dt_entry_total_size) = header.dt_entry_size.get().checked_mul(index) else {
+ return Err(anyhow!("Unexpected arithmetic result"))
+ .or_binder_exception(ExceptionCode::ILLEGAL_STATE);
+ };
+ let Some(dt_entry_offset) =
+ prev_dt_entry_total_size.checked_add(header.dt_entries_offset.get())
+ else {
+ return Err(anyhow!("Unexpected arithmetic result"))
+ .or_binder_exception(ExceptionCode::ILLEGAL_STATE);
+ };
+ let values = read_values(file, size_of::<DtTableEntry>(), dt_entry_offset.into())?;
+ let dt_table_entry = DtTableEntry::read_from(values.as_slice())
+ .with_context(|| format!("DtTableEntry at index {index} is invalid."))
+ .or_service_specific_exception(-1)?;
+ Ok(dt_table_entry)
+}
+
+fn filter_dtbo_from_img(
+ dtbo_img_file: &mut File,
+ entry: &DtTableEntry,
+ dtbo_fd: &ParcelFileDescriptor,
+) -> binder::Result<()> {
+ let dt_size = entry
+ .dt_size
+ .get()
+ .try_into()
+ .context("Failed to convert type")
+ .or_binder_exception(ExceptionCode::ILLEGAL_STATE)?;
+ let buffer = read_values(dtbo_img_file, dt_size, entry.dt_offset.get().into())?;
+
+ let mut dtbo_fd = dtbo_fd
+ .as_ref()
+ .try_clone()
+ .context("Failed to clone File from ParcelFileDescriptor")
+ .or_binder_exception(ExceptionCode::BAD_PARCELABLE)?;
+
+ // TODO(b/296796644): Filter dtbo.img, not writing all information.
+ dtbo_fd
+ .write_all(&buffer)
+ .context("Failed to write dtbo file")
+ .or_service_specific_exception(-1)?;
+ Ok(())
+}
+
+fn write_dtbo(dtbo_fd: &ParcelFileDescriptor) -> binder::Result<()> {
+ let dtbo_path = get_dtbo_img_path()?;
+ let mut dtbo_img = File::open(dtbo_path)
+ .context("Failed to open DTBO partition")
+ .or_service_specific_exception(-1)?;
+
+ let dt_table_header = get_dt_table_header(&mut dtbo_img)?;
+ let vm_dtbo_idx = system_properties::read("ro.boot.hypervisor.vm_dtbo_idx")
+ .context("Failed to read vm_dtbo_idx")
+ .or_service_specific_exception(-1)?
+ .ok_or_else(|| anyhow!("vm_dtbo_idx is none"))
+ .or_service_specific_exception(-1)?;
+ let vm_dtbo_idx = vm_dtbo_idx
+ .parse()
+ .context("vm_dtbo_idx is not an integer")
+ .or_service_specific_exception(-1)?;
+ let dt_table_entry = get_dt_table_entry(&mut dtbo_img, &dt_table_header, vm_dtbo_idx)?;
+ filter_dtbo_from_img(&mut dtbo_img, &dt_table_entry, dtbo_fd)?;
+ Ok(())
+}
diff --git a/vm_payload/Android.bp b/vm_payload/Android.bp
index ae0d1a6..49b7f5f 100644
--- a/vm_payload/Android.bp
+++ b/vm_payload/Android.bp
@@ -10,8 +10,6 @@
srcs: ["src/*.rs"],
include_dirs: ["include"],
prefer_rlib: true,
- // Require unsafe blocks for inside unsafe functions.
- flags: ["-Dunsafe_op_in_unsafe_fn"],
rustlibs: [
"android.system.virtualization.payload-rust",
"libandroid_logger",
diff --git a/vmbase/example/src/main.rs b/vmbase/example/src/main.rs
index a6f3bfa..ebd981c 100644
--- a/vmbase/example/src/main.rs
+++ b/vmbase/example/src/main.rs
@@ -16,8 +16,6 @@
#![no_main]
#![no_std]
-#![deny(unsafe_op_in_unsafe_fn)]
-#![deny(clippy::undocumented_unsafe_blocks)]
mod exceptions;
mod layout;
diff --git a/vmbase/src/lib.rs b/vmbase/src/lib.rs
index ca8756d..431e899 100644
--- a/vmbase/src/lib.rs
+++ b/vmbase/src/lib.rs
@@ -15,8 +15,6 @@
//! Basic functionality for bare-metal binaries to run in a VM under crosvm.
#![no_std]
-#![deny(unsafe_op_in_unsafe_fn)]
-#![deny(clippy::undocumented_unsafe_blocks)]
extern crate alloc;