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))
     }
 }