[rpc_binder] Use RPC binder over UDS for vm_payload_service

Test: atest MicrodroidTests ComposHostTestCases
Bug: 222479468
Change-Id: I61f82f6e2c93b7cf2793c1a812cddc0436c33d82
This commit is contained in:
Alice Wang 2022-10-24 09:42:40 +00:00
parent 37fc5501fb
commit 43c884b00a
5 changed files with 42 additions and 17 deletions

View File

@ -15,12 +15,12 @@
//! This module handles the interaction with virtual machine payload service. //! This module handles the interaction with virtual machine payload service.
use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{ use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
IVmPayloadService, VM_PAYLOAD_SERVICE_NAME, VM_APK_CONTENTS_PATH}; IVmPayloadService, VM_PAYLOAD_SERVICE_SOCKET_NAME, VM_APK_CONTENTS_PATH};
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use binder::{wait_for_interface, Strong, unstable_api::{AIBinder, new_spibinder}}; use binder::{Strong, unstable_api::{AIBinder, new_spibinder}};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use log::{error, info, Level}; use log::{error, info, Level};
use rpcbinder::run_vsock_rpc_server; use rpcbinder::{get_unix_domain_rpc_interface, run_vsock_rpc_server};
use std::ffi::CString; use std::ffi::CString;
use std::os::raw::{c_char, c_void}; use std::os::raw::{c_char, c_void};
@ -203,6 +203,6 @@ fn try_get_dice_attestation_cdi() -> Result<Vec<u8>> {
} }
fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> { fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> {
wait_for_interface(VM_PAYLOAD_SERVICE_NAME) get_unix_domain_rpc_interface(VM_PAYLOAD_SERVICE_SOCKET_NAME)
.context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_NAME)) .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_SOCKET_NAME))
} }

View File

@ -21,8 +21,8 @@ package android.system.virtualization.payload;
* Microdroid Manager for execution. * Microdroid Manager for execution.
*/ */
interface IVmPayloadService { interface IVmPayloadService {
/** Name of the service IVmPayloadService. */ /** Socket name of the service IVmPayloadService. */
const String VM_PAYLOAD_SERVICE_NAME = "virtual_machine_payload_service"; const String VM_PAYLOAD_SERVICE_SOCKET_NAME = "vm_payload_service";
/** Path to the APK contents path. */ /** Path to the APK contents path. */
const String VM_APK_CONTENTS_PATH = "/mnt/apk"; const String VM_APK_CONTENTS_PATH = "/mnt/apk";

View File

@ -6,3 +6,4 @@ service microdroid_manager /system/bin/microdroid_manager
oneshot oneshot
# SYS_BOOT is required to exec kexecload from microdroid_manager # SYS_BOOT is required to exec kexecload from microdroid_manager
capabilities AUDIT_CONTROL SYS_ADMIN SYS_BOOT capabilities AUDIT_CONTROL SYS_ADMIN SYS_BOOT
socket vm_payload_service stream 0666 system system

View File

@ -31,7 +31,7 @@ use android_system_virtualmachineservice::aidl::android::system::virtualmachines
use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::VM_APK_CONTENTS_PATH; use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::VM_APK_CONTENTS_PATH;
use anyhow::{anyhow, bail, ensure, Context, Error, Result}; use anyhow::{anyhow, bail, ensure, Context, Error, Result};
use apkverify::{get_public_key_der, verify, V4Signature}; use apkverify::{get_public_key_der, verify, V4Signature};
use binder::{ProcessState, Strong}; use binder::Strong;
use diced_utils::cbor::{encode_header, encode_number}; use diced_utils::cbor::{encode_header, encode_number};
use glob::glob; use glob::glob;
use itertools::sorted; use itertools::sorted;
@ -397,7 +397,6 @@ fn try_run_payload(service: &Strong<dyn IVirtualMachineService>) -> Result<i32>
wait_for_property_true(APK_MOUNT_DONE_PROP).context("Failed waiting for APK mount done")?; wait_for_property_true(APK_MOUNT_DONE_PROP).context("Failed waiting for APK mount done")?;
register_vm_payload_service(allow_restricted_apis, service.clone(), dice)?; register_vm_payload_service(allow_restricted_apis, service.clone(), dice)?;
ProcessState::start_thread_pool();
system_properties::write("dev.bootcomplete", "1").context("set dev.bootcomplete")?; system_properties::write("dev.bootcomplete", "1").context("set dev.bootcomplete")?;
exec_task(task, service).context("Failed to run payload") exec_task(task, service).context("Failed to run payload")

View File

@ -16,13 +16,17 @@
use crate::dice::DiceContext; use crate::dice::DiceContext;
use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{ use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
BnVmPayloadService, IVmPayloadService, VM_PAYLOAD_SERVICE_NAME}; BnVmPayloadService, IVmPayloadService, VM_PAYLOAD_SERVICE_SOCKET_NAME};
use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService; use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
use anyhow::{Context, Result}; use anyhow::{bail, Result};
use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong, add_service}; use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong};
use log::error; use log::{error, info};
use openssl::hkdf::hkdf; use openssl::hkdf::hkdf;
use openssl::md::Md; use openssl::md::Md;
use rpcbinder::run_init_unix_domain_rpc_server;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
/// Implementation of `IVmPayloadService`. /// Implementation of `IVmPayloadService`.
struct VmPayloadService { struct VmPayloadService {
@ -97,8 +101,29 @@ pub(crate) fn register_vm_payload_service(
VmPayloadService::new(allow_restricted_apis, vm_service, dice), VmPayloadService::new(allow_restricted_apis, vm_service, dice),
BinderFeatures::default(), BinderFeatures::default(),
); );
add_service(VM_PAYLOAD_SERVICE_NAME, vm_payload_binder.as_binder()) let (sender, receiver) = mpsc::channel();
.with_context(|| format!("Failed to register service {}", VM_PAYLOAD_SERVICE_NAME))?; thread::spawn(move || {
log::info!("{} is running", VM_PAYLOAD_SERVICE_NAME); let retval = run_init_unix_domain_rpc_server(
Ok(()) vm_payload_binder.as_binder(),
VM_PAYLOAD_SERVICE_SOCKET_NAME,
|| {
sender.send(()).unwrap();
},
);
if retval {
info!(
"The RPC server at '{}' has shut down gracefully.",
VM_PAYLOAD_SERVICE_SOCKET_NAME
);
} else {
error!("Premature termination of the RPC server '{}'.", VM_PAYLOAD_SERVICE_SOCKET_NAME);
}
});
match receiver.recv_timeout(Duration::from_millis(200)) {
Ok(()) => {
info!("The RPC server '{}' is running.", VM_PAYLOAD_SERVICE_SOCKET_NAME);
Ok(())
}
_ => bail!("Failed to register service '{}'", VM_PAYLOAD_SERVICE_SOCKET_NAME),
}
} }