diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index 61ed76773..b348bb1ff 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -347,6 +347,7 @@ impl Request { mapping: &Arc, ext_mapping: &BTreeMap>, msi_iova_space: (u64, u64), + input_range: Option<(u64, u64)>, ) -> result::Result { let desc = desc_chain .next() @@ -490,6 +491,13 @@ impl Request { return Err(Error::InvalidMapRequest); } + if let Some((lo, hi)) = input_range + && (req.virt_start < lo || req.virt_end > hi) + { + status = VIRTIO_IOMMU_S_RANGE; + return Err(Error::InvalidMapRequest); + } + // Copy the value to use it as a proper reference. let domain_id = req.domain; @@ -611,6 +619,13 @@ impl Request { .map_err(Error::GuestMemory)?; debug!("Unmap request 0x{req:x?}"); + if let Some((lo, hi)) = input_range + && (req.virt_start < lo || req.virt_end > hi) + { + status = VIRTIO_IOMMU_S_RANGE; + return Err(Error::InvalidUnmapRequest); + } + // Copy the value to use it as a proper reference. let domain_id = req.domain; let virt_start = req.virt_start; @@ -808,6 +823,7 @@ struct IommuEpollHandler { mapping: Arc, ext_mapping: Arc>>>, msi_iova_space: (u64, u64), + input_range: Option<(u64, u64)>, } impl IommuEpollHandler { @@ -820,6 +836,7 @@ impl IommuEpollHandler { &self.mapping, &self.ext_mapping.lock().unwrap(), self.msi_iova_space, + self.input_range, )?; self.request_queue @@ -1032,6 +1049,7 @@ pub struct Iommu { seccomp_action: SeccompAction, exit_evt: EventFd, msi_iova_space: (u64, u64), + input_range: Option<(u64, u64)>, } type EndpointsState = Vec<(u32, u32)>; @@ -1091,13 +1109,14 @@ impl Iommu { ..Default::default() }; - if address_width_bits < 64 { + let input_range = if address_width_bits < 64 { avail_features |= 1u64 << VIRTIO_IOMMU_F_INPUT_RANGE; - config.input_range = VirtioIommuRange64 { - start: 0, - end: (1u64 << address_width_bits) - 1, - } - } + let end = (1u64 << address_width_bits) - 1; + config.input_range = VirtioIommuRange64 { start: 0, end }; + Some((0, end)) + } else { + None + }; let mapping = Arc::new(IommuMapping { endpoints: Arc::new(RwLock::new(endpoints)), @@ -1124,6 +1143,7 @@ impl Iommu { seccomp_action, exit_evt, msi_iova_space, + input_range, }, mapping, )) @@ -1251,6 +1271,7 @@ impl VirtioDevice for Iommu { mapping: self.mapping.clone(), ext_mapping: self.ext_mapping.clone(), msi_iova_space: self.msi_iova_space, + input_range: self.input_range, }; let paused = self.common.paused.clone();