Merge changes If575a1fe,I929cb995
* changes:
[avb][test] Add verification tests to check tampered vbmeta
[avb] Test latest debug initrd passes the payload verification
diff --git a/pvmfw/avb/src/verify.rs b/pvmfw/avb/src/verify.rs
index 8105bab..9ba67bf 100644
--- a/pvmfw/avb/src/verify.rs
+++ b/pvmfw/avb/src/verify.rs
@@ -22,7 +22,7 @@
slice,
};
-static NULL_BYTE: &[u8] = b"\0";
+const NULL_BYTE: &[u8] = b"\0";
enum AvbIOError {
/// AVB_IO_RESULT_ERROR_OOM,
@@ -68,17 +68,10 @@
_ops: *mut AvbOps,
out_is_unlocked: *mut bool,
) -> AvbIOResult {
- if let Err(e) = is_not_null(out_is_unlocked) {
- return e.into();
- }
- // SAFETY: It is safe as the raw pointer `out_is_unlocked` is a valid pointer.
- unsafe {
- *out_is_unlocked = false;
- }
- AvbIOResult::AVB_IO_RESULT_OK
+ to_avb_io_result(write(out_is_unlocked, false))
}
-unsafe extern "C" fn get_preloaded_partition(
+extern "C" fn get_preloaded_partition(
ops: *mut AvbOps,
partition: *const c_char,
num_bytes: usize,
@@ -103,18 +96,8 @@
) -> Result<(), AvbIOError> {
let ops = as_ref(ops)?;
let partition = ops.as_ref().get_partition(partition)?;
- let out_pointer = to_nonnull(out_pointer)?;
- // SAFETY: It is safe as the raw pointer `out_pointer` is a nonnull pointer.
- unsafe {
- *out_pointer.as_ptr() = partition.as_ptr() as _;
- }
- let out_num_bytes_preloaded = to_nonnull(out_num_bytes_preloaded)?;
- // SAFETY: The raw pointer `out_num_bytes_preloaded` was created to point to a valid a `usize`
- // and we checked it is nonnull.
- unsafe {
- *out_num_bytes_preloaded.as_ptr() = partition.len().min(num_bytes);
- }
- Ok(())
+ write(out_pointer, partition.as_ptr() as *mut u8)?;
+ write(out_num_bytes_preloaded, partition.len().min(num_bytes))
}
extern "C" fn read_from_partition(
@@ -150,13 +133,7 @@
// is created to point to the `num_bytes` of bytes in memory.
let buffer_slice = unsafe { slice::from_raw_parts_mut(buffer.as_ptr() as *mut u8, num_bytes) };
copy_data_to_dst(partition, offset, buffer_slice)?;
- let out_num_read = to_nonnull(out_num_read)?;
- // SAFETY: The raw pointer `out_num_read` was created to point to a valid a `usize`
- // and we checked it is nonnull.
- unsafe {
- *out_num_read.as_ptr() = buffer_slice.len();
- }
- Ok(())
+ write(out_num_read, buffer_slice.len())
}
fn copy_data_to_dst(src: &[u8], offset: i64, dst: &mut [u8]) -> Result<(), AvbIOError> {
@@ -189,13 +166,7 @@
let partition = ops.as_ref().get_partition(partition)?;
let partition_size =
u64::try_from(partition.len()).map_err(|_| AvbIOError::InvalidValueSize)?;
- let out_size_num_bytes = to_nonnull(out_size_num_bytes)?;
- // SAFETY: The raw pointer `out_size_num_bytes` was created to point to a valid a `u64`
- // and we checked it is nonnull.
- unsafe {
- *out_size_num_bytes.as_ptr() = partition_size;
- }
- Ok(())
+ write(out_size_num_bytes, partition_size)
}
extern "C" fn read_rollback_index(
@@ -260,10 +231,14 @@
// Verifies the public key for the known partitions only.
ops.as_ref().get_partition(partition)?;
let trusted_public_key = ops.as_ref().trusted_public_key;
- let out_is_trusted = to_nonnull(out_is_trusted)?;
- // SAFETY: It is safe as the raw pointer `out_is_trusted` is a nonnull pointer.
+ write(out_is_trusted, public_key == trusted_public_key)
+}
+
+fn write<T>(ptr: *mut T, value: T) -> Result<(), AvbIOError> {
+ let ptr = to_nonnull(ptr)?;
+ // SAFETY: It is safe as the raw pointer `ptr` is a nonnull pointer.
unsafe {
- *out_is_trusted.as_ptr() = public_key == trusted_public_key;
+ *ptr.as_ptr() = value;
}
Ok(())
}
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 374b90f..df8ad84 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -193,6 +193,8 @@
&self,
requester_debug_pid: i32,
) -> binder::Result<Strong<dyn IGlobalVmContext>> {
+ check_manage_access()?;
+
let requester_uid = get_calling_uid();
let requester_debug_pid = requester_debug_pid as pid_t;
let state = &mut *self.state.lock().unwrap();
@@ -217,6 +219,8 @@
}
fn debugListVms(&self) -> binder::Result<Vec<VirtualMachineDebugInfo>> {
+ check_debug_access()?;
+
let state = &mut *self.state.lock().unwrap();
let cids = state
.held_contexts
@@ -499,7 +503,7 @@
/// Get a list of all currently running VMs. This method is only intended for debug purposes,
/// and as such is only permitted from the shell user.
fn debugListVms(&self) -> binder::Result<Vec<VirtualMachineDebugInfo>> {
- check_debug_access()?;
+ // Delegate to the global service, including checking the debug permission.
GLOBAL_SERVICE.debugListVms()
}
}
@@ -562,7 +566,10 @@
VirtualizationService::default()
}
- fn create_vm_context(&self, requester_debug_pid: pid_t) -> Result<(VmContext, Cid, PathBuf)> {
+ fn create_vm_context(
+ &self,
+ requester_debug_pid: pid_t,
+ ) -> binder::Result<(VmContext, Cid, PathBuf)> {
const NUM_ATTEMPTS: usize = 5;
for _ in 0..NUM_ATTEMPTS {
@@ -583,7 +590,10 @@
}
}
}
- bail!("Too many attempts to create VM context failed.");
+ Err(Status::new_service_specific_error_str(
+ -1,
+ Some("Too many attempts to create VM context failed."),
+ ))
}
fn create_vm_internal(
@@ -593,7 +603,11 @@
log_fd: Option<&ParcelFileDescriptor>,
is_protected: &mut bool,
) -> binder::Result<Strong<dyn IVirtualMachine>> {
- check_manage_access()?;
+ let requester_uid = get_calling_uid();
+ let requester_debug_pid = get_calling_pid();
+
+ // Allocating VM context checks the MANAGE_VIRTUAL_MACHINE permission.
+ let (vm_context, cid, temporary_directory) = self.create_vm_context(requester_debug_pid)?;
let is_custom = match config {
VirtualMachineConfig::RawConfig(_) => true,
@@ -609,18 +623,6 @@
check_use_custom_virtual_machine()?;
}
- let requester_uid = get_calling_uid();
- let requester_debug_pid = get_calling_pid();
-
- let (vm_context, cid, temporary_directory) =
- self.create_vm_context(requester_debug_pid).map_err(|e| {
- error!("Failed to create VmContext: {:?}", e);
- Status::new_service_specific_error_str(
- -1,
- Some(format!("Failed to create VmContext: {:?}", e)),
- )
- })?;
-
let state = &mut *self.state.lock().unwrap();
let console_fd = console_fd.map(clone_file).transpose()?;
let log_fd = log_fd.map(clone_file).transpose()?;