Include requester UID and SID in VM debug info.
Bug: 184131756
Test: Ran a vm manually with `vm` tool.
Change-Id: Ia0267231592dc964be0a3459bd9d6aa9dff001ca
diff --git a/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl b/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
index 9003bc3..d1ba9a6 100644
--- a/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
+++ b/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
@@ -19,4 +19,13 @@
parcelable VirtualMachineDebugInfo {
/** The CID assigned to the VM. */
int cid;
+ /** The UID of the process which requested the VM. */
+ int requester_uid;
+ /** The SID of the process which requested the VM. */
+ @nullable String requester_sid;
+ /**
+ * The PID of the process which requested the VM. Note that this process may no longer exist and
+ * the PID may have been reused for a different process, so this should not be trusted.
+ */
+ int requester_pid;
}
diff --git a/virtmanager/src/aidl.rs b/virtmanager/src/aidl.rs
index ff8ab30..98af714 100644
--- a/virtmanager/src/aidl.rs
+++ b/virtmanager/src/aidl.rs
@@ -27,6 +27,7 @@
self, Interface, ParcelFileDescriptor, StatusCode, Strong, ThreadState,
};
use log::error;
+use std::ffi::CStr;
use std::fs::File;
use std::sync::{Arc, Mutex, Weak};
@@ -58,7 +59,25 @@
let log_fd = log_fd
.map(|fd| fd.as_ref().try_clone().map_err(|_| StatusCode::UNKNOWN_ERROR))
.transpose()?;
- let instance = Arc::new(start_vm(config_fd.as_ref(), cid, log_fd)?);
+ let requester_uid = ThreadState::get_calling_uid();
+ let requester_sid = ThreadState::with_calling_sid(|sid| {
+ sid.and_then(|sid: &CStr| match sid.to_str() {
+ Ok(s) => Some(s.to_owned()),
+ Err(e) => {
+ error!("SID was not valid UTF-8: {:?}", e);
+ None
+ }
+ })
+ });
+ let requester_pid = ThreadState::get_calling_pid();
+ let instance = Arc::new(start_vm(
+ config_fd.as_ref(),
+ cid,
+ log_fd,
+ requester_uid,
+ requester_sid,
+ requester_pid,
+ )?);
// TODO(qwandor): keep track of which CIDs are currently in use so that we can reuse them.
state.next_cid = state.next_cid.checked_add(1).ok_or(StatusCode::UNKNOWN_ERROR)?;
state.add_vm(Arc::downgrade(&instance));
@@ -74,8 +93,15 @@
let state = &mut *self.state.lock().unwrap();
let vms = state.vms();
- let cids =
- vms.into_iter().map(|vm| VirtualMachineDebugInfo { cid: vm.cid as i32 }).collect();
+ let cids = vms
+ .into_iter()
+ .map(|vm| VirtualMachineDebugInfo {
+ cid: vm.cid as i32,
+ requester_uid: vm.requester_uid as i32,
+ requester_sid: vm.requester_sid.clone(),
+ requester_pid: vm.requester_pid,
+ })
+ .collect();
Ok(cids)
}
@@ -186,15 +212,23 @@
}
}
-/// Start a new VM instance from the given VM config filename. This assumes the VM is not already
+/// Start a new VM instance from the given VM config file. This assumes the VM is not already
/// running.
-fn start_vm(config_file: &File, cid: Cid, log_fd: Option<File>) -> binder::Result<VmInstance> {
+fn start_vm(
+ config_file: &File,
+ cid: Cid,
+ log_fd: Option<File>,
+ requester_uid: u32,
+ requester_sid: Option<String>,
+ requester_pid: i32,
+) -> binder::Result<VmInstance> {
let config = VmConfig::load(config_file).map_err(|e| {
error!("Failed to load VM config from {:?}: {:?}", config_file, e);
StatusCode::BAD_VALUE
})?;
- Ok(VmInstance::start(&config, cid, log_fd).map_err(|e| {
- error!("Failed to start VM from {:?}: {:?}", config_file, e);
- StatusCode::UNKNOWN_ERROR
- })?)
+ Ok(VmInstance::start(&config, cid, log_fd, requester_uid, requester_sid, requester_pid)
+ .map_err(|e| {
+ error!("Failed to start VM from {:?}: {:?}", config_file, e);
+ StatusCode::UNKNOWN_ERROR
+ })?)
}
diff --git a/virtmanager/src/crosvm.rs b/virtmanager/src/crosvm.rs
index c865357..bef9982 100644
--- a/virtmanager/src/crosvm.rs
+++ b/virtmanager/src/crosvm.rs
@@ -30,19 +30,39 @@
child: Child,
/// The CID assigned to the VM for vsock communication.
pub cid: Cid,
+ /// The UID of the process which requested the VM.
+ pub requester_uid: u32,
+ /// The SID of the process which requested the VM.
+ pub requester_sid: Option<String>,
+ /// The PID of the process which requested the VM. Note that this process may no longer exist
+ /// and the PID may have been reused for a different process, so this should not be trusted.
+ pub requester_pid: i32,
}
impl VmInstance {
/// Create a new `VmInstance` for the given process.
- fn new(child: Child, cid: Cid) -> VmInstance {
- VmInstance { child, cid }
+ fn new(
+ child: Child,
+ cid: Cid,
+ requester_uid: u32,
+ requester_sid: Option<String>,
+ requester_pid: i32,
+ ) -> VmInstance {
+ VmInstance { child, cid, requester_uid, requester_sid, requester_pid }
}
/// Start an instance of `crosvm` to manage a new VM. The `crosvm` instance will be killed when
/// the `VmInstance` is dropped.
- pub fn start(config: &VmConfig, cid: Cid, log_fd: Option<File>) -> Result<VmInstance, Error> {
+ pub fn start(
+ config: &VmConfig,
+ cid: Cid,
+ log_fd: Option<File>,
+ requester_uid: u32,
+ requester_sid: Option<String>,
+ requester_pid: i32,
+ ) -> Result<VmInstance, Error> {
let child = run_vm(config, cid, log_fd)?;
- Ok(VmInstance::new(child, cid))
+ Ok(VmInstance::new(child, cid, requester_uid, requester_sid, requester_pid))
}
}