Remove CAP_IPC_LOCK from crosvm, use CAP_SYS_RESOURCE on VS

Crosvm currently has a capability that allows it to mlock() unlimited
amounts of RAM, necessary for running protected VMs. This mechanims is
not compatible with switching to crosvm as a child process, so replace
it with setrlimit from virtualizationservice. The limit is set to
RLIM_INFINITY to preserve the original property.

Bug: 204298056
Bug: 245727626
Test: atest MicrodroidTestApp
Change-Id: Iec393f5c0548f7eac1ba162214b57350d8328637
This commit is contained in:
David Brazdil 2022-10-28 14:06:49 +01:00
parent 36a58d96e6
commit 533e34376b
2 changed files with 15 additions and 2 deletions

View File

@ -1 +1 @@
/bin/crosvm 0 2000 0755 capabilities=0x4000
/bin/virtualizationservice 0 2000 0755 capabilities=0x1000000 # CAP_SYS_RESOURCE

View File

@ -24,8 +24,8 @@ mod selinux;
use crate::aidl::{VirtualizationService, BINDER_SERVICE_IDENTIFIER, TEMPORARY_DIRECTORY};
use android_logger::{Config, FilterBuilder};
use android_system_virtualizationservice::aidl::android::system::virtualizationservice::IVirtualizationService::BnVirtualizationService;
use anyhow::{bail, Context, Error};
use binder::{register_lazy_service, BinderFeatures, ProcessState};
use anyhow::Error;
use log::{info, Level};
use std::fs::{remove_dir_all, remove_file, read_dir};
@ -44,6 +44,7 @@ fn main() {
),
);
remove_memlock_rlimit().expect("Failed to remove memlock rlimit");
clear_temporary_files().expect("Failed to delete old temporary files");
let service = VirtualizationService::init();
@ -53,6 +54,18 @@ fn main() {
ProcessState::join_thread_pool();
}
/// Set this PID's RLIMIT_MEMLOCK to RLIM_INFINITY to allow crosvm (a child process) to mlock()
/// arbitrary amounts of memory. This is necessary for spawning protected VMs.
fn remove_memlock_rlimit() -> Result<(), Error> {
let lim = libc::rlimit { rlim_cur: libc::RLIM_INFINITY, rlim_max: libc::RLIM_INFINITY };
// SAFETY - borrowing the new limit struct only
match unsafe { libc::setrlimit(libc::RLIMIT_MEMLOCK, &lim) } {
0 => Ok(()),
-1 => Err(std::io::Error::last_os_error()).context("setrlimit failed"),
n => bail!("Unexpected return value from setrlimit(): {}", n),
}
}
/// Remove any files under `TEMPORARY_DIRECTORY`.
fn clear_temporary_files() -> Result<(), Error> {
for dir_entry in read_dir(TEMPORARY_DIRECTORY)? {