[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.
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 binder::{wait_for_interface, Strong, unstable_api::{AIBinder, new_spibinder}};
use binder::{Strong, unstable_api::{AIBinder, new_spibinder}};
use lazy_static::lazy_static;
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::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>> {
wait_for_interface(VM_PAYLOAD_SERVICE_NAME)
.context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_NAME))
get_unix_domain_rpc_interface(VM_PAYLOAD_SERVICE_SOCKET_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.
*/
interface IVmPayloadService {
/** Name of the service IVmPayloadService. */
const String VM_PAYLOAD_SERVICE_NAME = "virtual_machine_payload_service";
/** Socket name of the service IVmPayloadService. */
const String VM_PAYLOAD_SERVICE_SOCKET_NAME = "vm_payload_service";
/** Path to the APK contents path. */
const String VM_APK_CONTENTS_PATH = "/mnt/apk";

View File

@ -6,3 +6,4 @@ service microdroid_manager /system/bin/microdroid_manager
oneshot
# SYS_BOOT is required to exec kexecload from microdroid_manager
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 anyhow::{anyhow, bail, ensure, Context, Error, Result};
use apkverify::{get_public_key_der, verify, V4Signature};
use binder::{ProcessState, Strong};
use binder::Strong;
use diced_utils::cbor::{encode_header, encode_number};
use glob::glob;
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")?;
register_vm_payload_service(allow_restricted_apis, service.clone(), dice)?;
ProcessState::start_thread_pool();
system_properties::write("dev.bootcomplete", "1").context("set dev.bootcomplete")?;
exec_task(task, service).context("Failed to run payload")

View File

@ -16,13 +16,17 @@
use crate::dice::DiceContext;
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 anyhow::{Context, Result};
use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong, add_service};
use log::error;
use anyhow::{bail, Result};
use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong};
use log::{error, info};
use openssl::hkdf::hkdf;
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`.
struct VmPayloadService {
@ -97,8 +101,29 @@ pub(crate) fn register_vm_payload_service(
VmPayloadService::new(allow_restricted_apis, vm_service, dice),
BinderFeatures::default(),
);
add_service(VM_PAYLOAD_SERVICE_NAME, vm_payload_binder.as_binder())
.with_context(|| format!("Failed to register service {}", VM_PAYLOAD_SERVICE_NAME))?;
log::info!("{} is running", VM_PAYLOAD_SERVICE_NAME);
Ok(())
let (sender, receiver) = mpsc::channel();
thread::spawn(move || {
let retval = run_init_unix_domain_rpc_server(
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),
}
}