diff --git a/block/src/lib.rs b/block/src/lib.rs index 9ad36ac83..a6ed32bc6 100644 --- a/block/src/lib.rs +++ b/block/src/lib.rs @@ -440,8 +440,9 @@ impl Request { let origin_ptr = mem .get_slice(data_addr, data_len) - .map_err(ExecuteError::GetHostAddress)? - .ptr_guard(); + .map_err(ExecuteError::GetHostAddress)?; + assert!(origin_ptr.len() >= data_len); + let origin_ptr = origin_ptr.ptr_guard(); // Verify the buffer alignment. // In case it's not properly aligned, an intermediate buffer is diff --git a/devices/src/pvmemcontrol.rs b/devices/src/pvmemcontrol.rs index f096be69f..d078a1db1 100644 --- a/devices/src/pvmemcontrol.rs +++ b/devices/src/pvmemcontrol.rs @@ -429,22 +429,20 @@ impl PvmemcontrolBusDevice { /// [`range_base`, `range_base` + `range_len`) is present in the guest fn operate_on_memory_range(&self, addr: u64, length: u64, f: F) -> result::Result<(), Error> where - F: FnOnce(*mut libc::c_void, libc::size_t) -> libc::c_int, + F: FnOnce(*mut libc::c_void, usize) -> libc::c_int, { let memory = self.mem.memory(); let range_base = GuestAddress(addr); let range_len = usize::try_from(length).map_err(|_| Error::InvalidRequest)?; // assume guest memory is not interleaved with vmm memory on the host. - if !memory.check_range(range_base, range_len) { + let Ok(slice) = memory.get_slice(range_base, range_len) else { return Err(Error::GuestMemory(GuestMemoryError::InvalidGuestAddress( range_base, ))); - } - let hva = memory - .get_host_address(range_base) - .map_err(Error::GuestMemory)?; - let res = f(hva as *mut libc::c_void, range_len as libc::size_t); + }; + assert!(slice.len() >= range_len); + let res = f(slice.ptr_guard_mut().as_ptr() as _, slice.len()); if res != 0 { return Err(Error::LibcFail(io::Error::last_os_error())); } diff --git a/net_util/src/queue_pair.rs b/net_util/src/queue_pair.rs index 0ad328ff9..6202833a1 100644 --- a/net_util/src/queue_pair.rs +++ b/net_util/src/queue_pair.rs @@ -67,8 +67,9 @@ impl TxVirtio { let buf = desc_chain .memory() .get_slice(desc_addr, desc.len() as usize) - .map_err(NetQueuePairError::GuestMemory)? - .ptr_guard_mut(); + .map_err(NetQueuePairError::GuestMemory)?; + assert!(buf.len() >= desc.len() as usize); + let buf = buf.ptr_guard_mut(); let iovec = libc::iovec { iov_base: buf.as_ptr() as *mut libc::c_void, iov_len: desc.len() as libc::size_t, @@ -208,8 +209,9 @@ impl RxVirtio { let buf = desc_chain .memory() .get_slice(desc_addr, desc.len() as usize) - .map_err(NetQueuePairError::GuestMemory)? - .ptr_guard_mut(); + .map_err(NetQueuePairError::GuestMemory)?; + assert!(buf.len() >= desc.len() as usize); + let buf = buf.ptr_guard_mut(); let iovec = libc::iovec { iov_base: buf.as_ptr() as *mut libc::c_void, iov_len: desc.len() as libc::size_t, diff --git a/virtio-devices/src/balloon.rs b/virtio-devices/src/balloon.rs index d7ce19262..dfb81d0a9 100644 --- a/virtio-devices/src/balloon.rs +++ b/virtio-devices/src/balloon.rs @@ -174,12 +174,15 @@ impl BalloonEpollHandler { range_len: usize, advice: libc::c_int, ) -> result::Result<(), Error> { - let hva = memory - .get_host_address(range_base) + let slice = memory + .get_slice(range_base, range_len) .map_err(Error::GuestMemory)?; + assert!(slice.len() >= range_len); let res = - // SAFETY: Need unsafe to do syscall madvise - unsafe { libc::madvise(hva as *mut libc::c_void, range_len as libc::size_t, advice) }; + // SAFETY: FFI call with valid arguments, guaranteed by VolatileSlice + unsafe { + libc::madvise(slice.ptr_guard_mut().as_ptr() as *mut libc::c_void, + range_len as libc::size_t, advice) }; if res != 0 { return Err(Error::MadviseFail(io::Error::last_os_error())); } diff --git a/virtio-devices/src/vdpa.rs b/virtio-devices/src/vdpa.rs index 7d4bcb96a..7c38e2f30 100644 --- a/virtio-devices/src/vdpa.rs +++ b/virtio-devices/src/vdpa.rs @@ -19,7 +19,7 @@ use vhost::{VhostBackend, VringConfigData}; use virtio_queue::desc::RawDescriptor; use virtio_queue::{Queue, QueueT}; use vm_device::dma_mapping::ExternalDmaMapping; -use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic}; +use vm_memory::{GuestAddress, GuestAddressSpace, GuestMemoryAtomic}; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; use vm_virtio::{AccessPlatform, Translatable}; use vmm_sys_util::eventfd::EventFd; @@ -27,7 +27,7 @@ use vmm_sys_util::eventfd::EventFd; use crate::{ ActivateError, ActivateResult, DEVICE_ACKNOWLEDGE, DEVICE_DRIVER, DEVICE_DRIVER_OK, DEVICE_FEATURES_OK, GuestMemoryMmap, VIRTIO_F_IOMMU_PLATFORM, VirtioCommon, VirtioDevice, - VirtioInterrupt, VirtioInterruptType, + VirtioInterrupt, VirtioInterruptType, get_host_address_range, }; #[derive(Error, Debug)] @@ -548,11 +548,10 @@ impl VdpaDmaMapping { impl ExternalDmaMapping for VdpaDmaMapping { fn map(&self, iova: u64, gpa: u64, size: u64) -> result::Result<(), io::Error> { + let usize_size = size.try_into().unwrap(); let mem = self.memory.memory(); let guest_addr = GuestAddress(gpa); - let user_addr = if mem.check_range(guest_addr, size as usize) { - mem.get_host_address(guest_addr).unwrap() as *const u8 - } else { + let Some(user_addr) = get_host_address_range(&*mem, guest_addr, usize_size) else { return Err(io::Error::other(format!( "failed to convert guest address 0x{gpa:x} into \ host user virtual address" @@ -563,7 +562,7 @@ impl ExternalDmaMapping for VdpaDmaMapping