Merge "[rialto] Enable the host and service VM vsock connection" into main
diff --git a/authfs/src/fusefs.rs b/authfs/src/fusefs.rs
index bddf2c3..64b340a 100644
--- a/authfs/src/fusefs.rs
+++ b/authfs/src/fusefs.rs
@@ -993,8 +993,8 @@
fn statfs(&self, _ctx: Context, _inode: Self::Inode) -> io::Result<libc::statvfs64> {
let remote_stat = self.remote_fs_stats_reader.statfs()?;
- // Safe because we are zero-initializing a struct with only POD fields. Not all fields
- // matter to FUSE. See also:
+ // SAFETY: We are zero-initializing a struct with only POD fields. Not all fields matter to
+ // FUSE. See also:
// https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/fs/fuse/inode.c?h=v5.15#n460
let mut st: libc::statvfs64 = unsafe { zeroed() };
diff --git a/compos/composd/src/fd_server_helper.rs b/compos/composd/src/fd_server_helper.rs
index 777ec27..24371b5 100644
--- a/compos/composd/src/fd_server_helper.rs
+++ b/compos/composd/src/fd_server_helper.rs
@@ -107,8 +107,9 @@
fn create_pipe() -> Result<(File, File)> {
let (raw_read, raw_write) = pipe2(OFlag::O_CLOEXEC)?;
- // SAFETY: We are the sole owners of these fds as they were just created.
+ // SAFETY: We are the sole owner of raw_read and it is valid as it was just created.
let read_fd = unsafe { File::from_raw_fd(raw_read) };
+ // SAFETY: We are the sole owner of raw_write and it is valid as it was just created.
let write_fd = unsafe { File::from_raw_fd(raw_write) };
Ok((read_fd, write_fd))
}
diff --git a/compos/src/compsvc_main.rs b/compos/src/compsvc_main.rs
index 77e2daa..b0fc323 100644
--- a/compos/src/compsvc_main.rs
+++ b/compos/src/compsvc_main.rs
@@ -50,11 +50,11 @@
debug!("compsvc is starting as a rpc service.");
let param = ptr::null_mut();
let mut service = compsvc::new_binder()?.as_binder();
+ let service = service.as_native_mut() as *mut AIBinder;
+ // SAFETY: We hold a strong pointer, so the raw pointer remains valid. The bindgen AIBinder
+ // is the same type as sys::AIBinder. It is safe for on_ready to be invoked at any time, with
+ // any parameter.
unsafe {
- // SAFETY: We hold a strong pointer, so the raw pointer remains valid. The bindgen AIBinder
- // is the same type as sys::AIBinder.
- let service = service.as_native_mut() as *mut AIBinder;
- // SAFETY: It is safe for on_ready to be invoked at any time, with any parameter.
AVmPayload_runVsockRpcServer(service, COMPOS_VSOCK_PORT, Some(on_ready), param);
}
Ok(())
diff --git a/encryptedstore/src/main.rs b/encryptedstore/src/main.rs
index 86fa6da..1a16f49 100644
--- a/encryptedstore/src/main.rs
+++ b/encryptedstore/src/main.rs
@@ -153,6 +153,9 @@
let mountpoint = CString::new(mountpoint.as_os_str().as_bytes())?;
let fstype = CString::new("ext4").unwrap();
+ // SAFETY: The source, target and filesystemtype are valid C strings. For ext4, data is expected
+ // to be a C string as well, which it is. None of these pointers are retained after mount
+ // returns.
let ret = unsafe {
libc::mount(
source.as_ptr(),
diff --git a/libs/capabilities/src/caps.rs b/libs/capabilities/src/caps.rs
index 1f44a34..bc17fa8 100644
--- a/libs/capabilities/src/caps.rs
+++ b/libs/capabilities/src/caps.rs
@@ -26,8 +26,8 @@
/// Removes inheritable capabilities set for this process.
/// See: https://man7.org/linux/man-pages/man7/capabilities.7.html
pub fn drop_inheritable_caps() -> Result<()> {
+ // SAFETY: we do not manipulate memory handled by libcap.
unsafe {
- // SAFETY: we do not manipulate memory handled by libcap.
let caps = cap_get_proc();
scopeguard::defer! {
cap_free(caps as *mut std::os::raw::c_void);
@@ -49,8 +49,8 @@
pub fn drop_bounding_set() -> Result<()> {
let mut cap_id: cap_value_t = 0;
while cap_id <= CAP_LAST_CAP.try_into().unwrap() {
+ // SAFETY: we do not manipulate memory handled by libcap.
unsafe {
- // SAFETY: we do not manipulate memory handled by libcap.
if cap_drop_bound(cap_id) == -1 {
let e = Errno::last();
bail!("cap_drop_bound failed for {}: {:?}", cap_id, e);
diff --git a/microdroid_manager/src/dice.rs b/microdroid_manager/src/dice.rs
index bacefcd..8e078ea 100644
--- a/microdroid_manager/src/dice.rs
+++ b/microdroid_manager/src/dice.rs
@@ -78,7 +78,7 @@
let mmap_size =
file.read_u64::<NativeEndian>()
.map_err(|error| Error::new(error).context("Reading driver"))? as usize;
- // It's safe to map the driver as the service will only create a single
+ // SAFETY: It's safe to map the driver as the service will only create a single
// mapping per process.
let mmap_addr = unsafe {
let fd = file.as_raw_fd();
@@ -87,10 +87,10 @@
if mmap_addr == MAP_FAILED {
bail!("Failed to mmap {:?}", driver_path);
}
- // The slice is created for the region of memory that was just
+ let mmap_buf =
+ // SAFETY: The slice is created for the region of memory that was just
// successfully mapped into the process address space so it will be
// accessible and not referenced from anywhere else.
- let mmap_buf =
unsafe { slice::from_raw_parts((mmap_addr as *const u8).as_ref().unwrap(), mmap_size) };
let bcc_handover =
bcc_handover_parse(mmap_buf).map_err(|_| anyhow!("Failed to parse Bcc Handover"))?;
@@ -149,9 +149,9 @@
impl Drop for DiceDriver<'_> {
fn drop(&mut self) {
if let &mut Self::Real { mmap_addr, mmap_size, .. } = self {
- // All references to the mapped region have the same lifetime as self. Since self is
- // being dropped, so are all the references to the mapped region meaning its safe to
- // unmap.
+ // SAFETY: All references to the mapped region have the same lifetime as self. Since
+ // self is being dropped, so are all the references to the mapped region meaning it's
+ // safe to unmap.
let ret = unsafe { munmap(mmap_addr, mmap_size) };
if ret != 0 {
log::warn!("Failed to munmap ({})", ret);
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 1cdcde1..319d2df 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -193,7 +193,7 @@
/// Prepares a socket file descriptor for the vm payload service.
///
-/// # Safety requirement
+/// # Safety
///
/// The caller must ensure that this function is the only place that claims ownership
/// of the file descriptor and it is called only once.
@@ -267,6 +267,8 @@
if Path::new(ENCRYPTEDSTORE_BACKING_DEVICE).exists() {
let mountpoint = CString::new(ENCRYPTEDSTORE_MOUNTPOINT).unwrap();
+ // SAFETY: `mountpoint` is a valid C string. `syncfs` and `close` are safe for any parameter
+ // values.
let ret = unsafe {
let dirfd = libc::open(
mountpoint.as_ptr(),
@@ -856,19 +858,15 @@
}
};
+ // SAFETY: We are not accessing any resource of the parent process. This means we can't make any
+ // log calls inside the closure.
unsafe {
- // SAFETY: we are not accessing any resource of the parent process.
command.pre_exec(|| {
- info!("dropping capabilities before executing payload");
// It is OK to continue with payload execution even if the calls below fail, since
// whether process can use a capability is controlled by the SELinux. Dropping the
// capabilities here is just another defense-in-depth layer.
- if let Err(e) = cap::drop_inheritable_caps() {
- error!("failed to drop inheritable capabilities: {:?}", e);
- }
- if let Err(e) = cap::drop_bounding_set() {
- error!("failed to drop bounding set: {:?}", e);
- }
+ let _ = cap::drop_inheritable_caps();
+ let _ = cap::drop_bounding_set();
Ok(())
});
}
diff --git a/microdroid_manager/src/swap.rs b/microdroid_manager/src/swap.rs
index 2f4d176..c2b20ac 100644
--- a/microdroid_manager/src/swap.rs
+++ b/microdroid_manager/src/swap.rs
@@ -48,7 +48,7 @@
.checked_mul(512)
.ok_or_else(|| anyhow!("sysfs_size too large"))?;
- // safe because we give a constant and known-valid sysconf parameter
+ // SAFETY: We give a constant and known-valid sysconf parameter.
let pagesize = unsafe { libc::sysconf(libc::_SC_PAGE_SIZE) as u64 };
let mut f = OpenOptions::new().read(false).write(true).open(format!("/dev/{}", dev))?;
@@ -75,7 +75,7 @@
/// Simple "swapon", using libc:: wrapper.
fn swapon(dev: &str) -> Result<()> {
let swapon_arg = std::ffi::CString::new(format!("/dev/{}", dev))?;
- // safe because we give a nul-terminated string and check the result
+ // SAFETY: We give a nul-terminated string and check the result.
let res = unsafe { libc::swapon(swapon_arg.as_ptr(), 0) };
if res != 0 {
return Err(anyhow!("Failed to swapon: {}", Error::last_os_error()));
diff --git a/pvmfw/avb/tests/api_test.rs b/pvmfw/avb/tests/api_test.rs
index aa9ed36..3b78663 100644
--- a/pvmfw/avb/tests/api_test.rs
+++ b/pvmfw/avb/tests/api_test.rs
@@ -244,8 +244,8 @@
let footer = extract_avb_footer(&kernel)?;
assert!(footer.vbmeta_offset < total_len);
let vbmeta_offset_addr = ptr::addr_of!(footer.vbmeta_offset) as *const u8;
- // SAFETY: It is safe as both raw pointers `vbmeta_offset_addr` and `footer` are not null.
let vbmeta_offset_start =
+ // SAFETY: It is safe as both raw pointers `vbmeta_offset_addr` and `footer` are not null.
unsafe { vbmeta_offset_addr.offset_from(ptr::addr_of!(footer) as *const u8) };
let footer_start = kernel.len() - size_of::<AvbFooter>();
let vbmeta_offset_start = footer_start + usize::try_from(vbmeta_offset_start)?;
diff --git a/rialto/tests/test.rs b/rialto/tests/test.rs
index 31a0c55..4ad8eb8 100644
--- a/rialto/tests/test.rs
+++ b/rialto/tests/test.rs
@@ -158,6 +158,7 @@
// SAFETY: These are new FDs with no previous owner.
let reader = unsafe { File::from_raw_fd(reader_fd) };
+ // SAFETY: These are new FDs with no previous owner.
let writer = unsafe { File::from_raw_fd(writer_fd) };
thread::spawn(|| {
diff --git a/vmbase/example/tests/test.rs b/vmbase/example/tests/test.rs
index 3594523..2b6dfbc 100644
--- a/vmbase/example/tests/test.rs
+++ b/vmbase/example/tests/test.rs
@@ -143,6 +143,7 @@
// SAFETY: These are new FDs with no previous owner.
let reader = unsafe { File::from_raw_fd(reader_fd) };
+ // SAFETY: These are new FDs with no previous owner.
let writer = unsafe { File::from_raw_fd(writer_fd) };
Ok((reader, writer))
diff --git a/zipfuse/src/main.rs b/zipfuse/src/main.rs
index 20d6fd6..e8be42c 100644
--- a/zipfuse/src/main.rs
+++ b/zipfuse/src/main.rs
@@ -31,7 +31,7 @@
use std::fs::{File, OpenOptions};
use std::io;
use std::io::Read;
-use std::mem::size_of;
+use std::mem::{size_of, MaybeUninit};
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::path::PathBuf;
@@ -192,7 +192,8 @@
#[allow(clippy::useless_conversion)]
fn stat_from(&self, inode: Inode) -> io::Result<libc::stat64> {
let inode_data = self.find_inode(inode)?;
- let mut st = unsafe { std::mem::MaybeUninit::<libc::stat64>::zeroed().assume_init() };
+ // SAFETY: All fields of stat64 are valid for zero byte patterns.
+ let mut st = unsafe { MaybeUninit::<libc::stat64>::zeroed().assume_init() };
st.st_dev = 0;
st.st_nlink = if let Some(directory) = inode_data.get_directory() {
(2 + directory.len() as libc::nlink_t).into()