Merge "Replace sleep with polling in AuthFsHostTest"
diff --git a/apex/Android.bp b/apex/Android.bp
index fa3806f..bb73630 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -35,6 +35,8 @@
"vm",
],
filesystems: ["microdroid"],
+ prebuilts: ["com.android.virt.init.rc"],
+ file_contexts: ":com.android.virt-file_contexts",
}
apex_key {
@@ -47,3 +49,9 @@
name: "com.android.virt.certificate",
certificate: "com.android.virt",
}
+
+prebuilt_etc {
+ name: "com.android.virt.init.rc",
+ src: "virtmanager.rc",
+ filename: "init.rc",
+}
diff --git a/apex/virtmanager.rc b/apex/virtmanager.rc
new file mode 100644
index 0000000..4a41154
--- /dev/null
+++ b/apex/virtmanager.rc
@@ -0,0 +1,19 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+service virtmanager /apex/com.android.virt/bin/virtmanager
+ class main
+ user virtmanager
+ group virtmanager
+ disabled
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index f853b75..4ddc03c 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -35,7 +35,7 @@
android_filesystem {
name: "microdroid",
use_avb: true,
- avb_private_key: "microdroid.pem",
+ avb_private_key: ":avb_testkey_rsa4096",
avb_algorithm: "SHA256_RSA4096",
partition_name: "system",
deps: [
@@ -57,16 +57,14 @@
"tombstoned",
"cgroups.json",
- // These files are temporary and only for test.
- // TODO(b/178993690): migrate cil files to Soong
- "microdroid_plat_mapping_file",
- "microdroid_plat_sepolicy_and_mapping.sha256",
+ "plat_sepolicy_and_mapping.sha256",
] + microdroid_shell_and_utilities,
multilib: {
common: {
deps: [
"com.android.runtime",
"plat_sepolicy.cil",
+ "plat_mapping_file",
"plat_file_contexts",
"plat_hwservice_contexts",
"plat_property_contexts",
@@ -94,12 +92,18 @@
use_avb: true,
deps: [
"microdroid_plat_sepolicy_vers.txt",
- "microdroid_vendor_sepolicy.cil",
- "microdroid_plat_pub_versioned.cil",
"microdroid_precompiled_sepolicy",
"microdroid_precompiled_sepolicy.plat_sepolicy_and_mapping.sha256",
],
- avb_private_key: "microdroid.pem",
+ multilib: {
+ common: {
+ deps: [
+ "microdroid_vendor_sepolicy.cil",
+ "microdroid_plat_pub_versioned.cil",
+ ],
+ },
+ },
+ avb_private_key: ":avb_testkey_rsa4096",
avb_algorithm: "SHA256_RSA4096",
file_contexts: "microdroid_vendor_file_contexts",
}
@@ -117,21 +121,14 @@
sparse: true,
// TODO(b/181107248): remove this hard-coded value
size: "104857600",
- groups: [
+ default_group: [
{
- name: "mygroup",
- // TODO(b/181107248): remove this hard-coded value
- size: "80000000",
- partitions: [
- {
- name: "system",
- filesystem: ":microdroid",
- },
- {
- name: "vendor",
- filesystem: ":microdroid_vendor",
- },
- ],
+ name: "system",
+ filesystem: ":microdroid",
+ },
+ {
+ name: "vendor",
+ filesystem: ":microdroid_vendor",
},
],
}
@@ -157,14 +154,12 @@
"printk.devkmsg=on " +
"androidboot.first_stage_console=1 " +
"androidboot.hardware=microdroid " +
- "androidboot.boot_devices=10000.pci " +
- // TODO(b/181747352) remove this to enforce selinux
- "androidboot.selinux=permissive",
+ "androidboot.boot_devices=10000.pci ",
dtb_prebuilt: "dummy_dtb.img",
header_version: "4",
partition_name: "boot",
use_avb: true,
- avb_private_key: "microdroid.pem",
+ avb_private_key: ":avb_testkey_rsa4096",
}
android_filesystem {
@@ -193,7 +188,7 @@
vendor_boot: true,
partition_name: "vendor_boot",
use_avb: true,
- avb_private_key: "microdroid.pem",
+ avb_private_key: ":avb_testkey_rsa4096",
}
android_filesystem {
@@ -244,29 +239,10 @@
cmd: "$(location mkenvimage_host) -s 4096 -o $(out) $(in)",
}
-genrule {
- name: "microdroid_plat_sepolicy_and_mapping.sha256_gen",
- srcs: [
- ":plat_sepolicy.cil",
- ":microdroid_plat_mapping_file",
- ],
- out: ["plat_sepolicy_and_mapping.sha256"],
- cmd: "cat $(in) | sha256sum | cut -d' ' -f1 > $(out)",
-}
-
-// sepolicy sha256 for system
-prebuilt_etc {
- name: "microdroid_plat_sepolicy_and_mapping.sha256",
- src: ":microdroid_plat_sepolicy_and_mapping.sha256_gen",
- filename: "plat_sepolicy_and_mapping.sha256",
- relative_install_path: "selinux",
- installable: false,
-}
-
-// sepolicy sha256 for vendor (filename differs)
+// sepolicy sha256 for vendor
prebuilt_etc {
name: "microdroid_precompiled_sepolicy.plat_sepolicy_and_mapping.sha256",
- src: ":microdroid_plat_sepolicy_and_mapping.sha256_gen",
+ src: ":plat_sepolicy_and_mapping.sha256_gen",
filename: "precompiled_sepolicy.plat_sepolicy_and_mapping.sha256",
relative_install_path: "selinux",
installable: false,
@@ -277,7 +253,7 @@
tools: ["secilc"],
srcs: [
":plat_sepolicy.cil",
- ":microdroid_plat_mapping_file",
+ ":plat_mapping_file",
":microdroid_plat_pub_versioned.cil",
":microdroid_vendor_sepolicy.cil",
],
@@ -296,7 +272,7 @@
vbmeta {
name: "microdroid_vbmeta",
partition_name: "vbmeta",
- private_key: "microdroid.pem",
+ private_key: ":avb_testkey_rsa4096",
partitions: [
"microdroid_vendor",
"microdroid_vendor_boot-5.10",
@@ -305,12 +281,12 @@
{
name: "vbmeta_system",
rollback_index_location: 1,
- private_key: "microdroid.pem",
+ private_key: ":avb_testkey_rsa4096",
},
{
name: "boot",
rollback_index_location: 2,
- private_key: "microdroid.pem",
+ private_key: ":avb_testkey_rsa4096",
},
],
}
@@ -318,7 +294,7 @@
vbmeta {
name: "microdroid_vbmeta_system",
partition_name: "vbmeta_system",
- private_key: "microdroid.pem",
+ private_key: ":avb_testkey_rsa4096",
partitions: [
"microdroid",
],
diff --git a/microdroid/microdroid.pem b/microdroid/microdroid.pem
deleted file mode 100644
index 2c9de45..0000000
--- a/microdroid/microdroid.pem
+++ /dev/null
@@ -1,51 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-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
------END RSA PRIVATE KEY-----
diff --git a/tests/vsock_test.cc b/tests/vsock_test.cc
index 57a03ca..0df1c5d 100644
--- a/tests/vsock_test.cc
+++ b/tests/vsock_test.cc
@@ -27,10 +27,10 @@
#include "android-base/logging.h"
#include "android-base/parseint.h"
#include "android-base/unique_fd.h"
-
#include "virt/VirtualizationTest.h"
using namespace android::base;
+using namespace android::os;
namespace virt {
@@ -58,7 +58,9 @@
ASSERT_EQ(ret, 0) << strerror(errno);
sp<IVirtualMachine> vm;
- status = mVirtManager->startVm(String16(kVmConfigPath), std::nullopt, &vm);
+ unique_fd vm_config_fd(open(kVmConfigPath, O_RDONLY | O_CLOEXEC));
+ status =
+ mVirtManager->startVm(ParcelFileDescriptor(std::move(vm_config_fd)), std::nullopt, &vm);
ASSERT_TRUE(status.isOk()) << "Error starting VM: " << status;
int32_t cid;
diff --git a/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl b/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl
index ab03c18..c2fc719 100644
--- a/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl
+++ b/virtmanager/aidl/android/system/virtmanager/IVirtManager.aidl
@@ -23,7 +23,8 @@
* Start the VM with the given config file, and return a handle to it. If `logFd` is provided
* then console logs from the VM will be sent to it.
*/
- IVirtualMachine startVm(String configPath, in @nullable ParcelFileDescriptor logFd);
+ IVirtualMachine startVm(
+ in ParcelFileDescriptor configFd, in @nullable ParcelFileDescriptor logFd);
/**
* Get a list of all currently running VMs. This method is only intended for debug purposes,
diff --git a/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl b/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
index d877a56..d1ba9a6 100644
--- a/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
+++ b/virtmanager/aidl/android/system/virtmanager/VirtualMachineDebugInfo.aidl
@@ -19,10 +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 filename of the config file used to start the VM. This may have changed since it was
- * read so it shouldn't be trusted; it is only stored for debugging purposes.
+ * 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.
*/
- String configPath;
+ int requester_pid;
}
diff --git a/virtmanager/src/aidl.rs b/virtmanager/src/aidl.rs
index 8c963d2..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};
@@ -50,7 +51,7 @@
/// Returns a binder `IVirtualMachine` object referring to it, as a handle for the client.
fn startVm(
&self,
- config_path: &str,
+ config_fd: &ParcelFileDescriptor,
log_fd: Option<&ParcelFileDescriptor>,
) -> binder::Result<Strong<dyn IVirtualMachine>> {
let state = &mut *self.state.lock().unwrap();
@@ -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_path, 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));
@@ -78,7 +97,9 @@
.into_iter()
.map(|vm| VirtualMachineDebugInfo {
cid: vm.cid as i32,
- configPath: vm.config_path.clone(),
+ requester_uid: vm.requester_uid as i32,
+ requester_sid: vm.requester_sid.clone(),
+ requester_pid: vm.requester_pid,
})
.collect();
Ok(cids)
@@ -191,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_path: &str, cid: Cid, log_fd: Option<File>) -> binder::Result<VmInstance> {
- let config = VmConfig::load(config_path).map_err(|e| {
- error!("Failed to load VM config {}: {:?}", config_path, e);
+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, config_path, log_fd).map_err(|e| {
- error!("Failed to start VM {}: {:?}", config_path, 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/config.rs b/virtmanager/src/config.rs
index d8cb06f..0b12c0b 100644
--- a/virtmanager/src/config.rs
+++ b/virtmanager/src/config.rs
@@ -14,7 +14,7 @@
//! Function and types for VM configuration.
-use anyhow::{bail, Context, Error};
+use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
use std::fs::File;
use std::io::BufReader;
@@ -51,8 +51,7 @@
}
/// Load the configuration for a VM from the given JSON file.
- pub fn load(path: &str) -> Result<VmConfig, Error> {
- let file = File::open(path).with_context(|| format!("Failed to open {}", path))?;
+ pub fn load(file: &File) -> Result<VmConfig, Error> {
let buffered = BufReader::new(file);
Ok(serde_json::from_reader(buffered)?)
}
diff --git a/virtmanager/src/crosvm.rs b/virtmanager/src/crosvm.rs
index 814a1a7..bef9982 100644
--- a/virtmanager/src/crosvm.rs
+++ b/virtmanager/src/crosvm.rs
@@ -30,15 +30,25 @@
child: Child,
/// The CID assigned to the VM for vsock communication.
pub cid: Cid,
- /// The filename of the config file that was used to start the VM. This may have changed since
- /// it was read so it shouldn't be trusted; it is only stored for debugging purposes.
- pub config_path: String,
+ /// 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, config_path: &str) -> VmInstance {
- VmInstance { child, cid, config_path: config_path.to_owned() }
+ 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
@@ -46,11 +56,13 @@
pub fn start(
config: &VmConfig,
cid: Cid,
- config_path: &str,
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, config_path))
+ Ok(VmInstance::new(child, cid, requester_uid, requester_sid, requester_pid))
}
}
diff --git a/vm/src/main.rs b/vm/src/main.rs
index 8c2a084..1f39e4a 100644
--- a/vm/src/main.rs
+++ b/vm/src/main.rs
@@ -77,9 +77,12 @@
daemonize: bool,
) -> Result<(), Error> {
let config_filename = config_path.to_str().context("Failed to parse VM config path")?;
+ let config_file = ParcelFileDescriptor::new(
+ File::open(config_filename).context("Failed to open config file")?,
+ );
let stdout_file = ParcelFileDescriptor::new(duplicate_stdout()?);
let stdout = if daemonize { None } else { Some(&stdout_file) };
- let vm = virt_manager.startVm(config_filename, stdout).context("Failed to start VM")?;
+ let vm = virt_manager.startVm(&config_file, stdout).context("Failed to start VM")?;
let cid = vm.getCid().context("Failed to get CID")?;
println!("Started VM from {} with CID {}.", config_filename, cid);