From 8f6a6a85e0ac3c9ad64e98256a3955f330372104 Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Fri, 27 Jun 2025 18:07:56 -0400 Subject: [PATCH] virtio-devices: mark Vdpa::dma_map as unsafe I believe that its only caller used it safely, but it is still better to mark the code as unsafe. Also add additional validity checks. Signed-off-by: Demi Marie Obenour --- virtio-devices/src/vdpa.rs | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/virtio-devices/src/vdpa.rs b/virtio-devices/src/vdpa.rs index e1f7dd0d6..7d4bcb96a 100644 --- a/virtio-devices/src/vdpa.rs +++ b/virtio-devices/src/vdpa.rs @@ -326,17 +326,28 @@ impl Vdpa { .map_err(Error::SetStatus) } - fn dma_map( + /// # SAFETY + /// + /// `host_vaddr` must point to `size` bytes of valid memory. + unsafe fn dma_map( &mut self, iova: u64, size: u64, host_vaddr: *const u8, readonly: bool, ) -> Result<()> { - let iova_last = iova + size - 1; + let Some(iova_last) = iova.checked_add(size) else { + return Err(Error::InvalidIovaRange(iova, u64::MAX)); + }; + let Some(iova_last) = iova_last.checked_sub(1) else { + return Err(Error::InvalidIovaRange(0, 0)); + }; if iova < self.iova_range.first || iova_last > self.iova_range.last { return Err(Error::InvalidIovaRange(iova, iova_last)); } + if isize::try_from(size).is_err() { + return Err(Error::InvalidIovaRange(iova, iova_last)); + } assert!(self.vhost.is_some()); self.vhost @@ -552,16 +563,20 @@ impl ExternalDmaMapping for VdpaDmaMapping std::result::Result<(), std::io::Error> {