From 634c53ea506c389d0ae87e2938d8eea89675e6b8 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Thu, 28 Apr 2022 18:20:39 +0200 Subject: [PATCH] vmm: config: Validate provided identifiers are unique A valid configuration means we can only accept unique identifiers from the user. Signed-off-by: Sebastien Boeuf --- vmm/src/config.rs | 76 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/vmm/src/config.rs b/vmm/src/config.rs index 78c37f468..ae1b1b345 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -8,7 +8,7 @@ use net_util::MacAddr; use option_parser::{ ByteSized, IntegerList, OptionParser, OptionParserError, StringList, Toggle, Tuple, }; -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use std::convert::From; use std::fmt; use std::net::Ipv4Addr; @@ -170,6 +170,8 @@ pub enum ValidationError { OnIommuSegment(u16), // On a IOMMU segment but IOMMU not suported IommuNotSupported(u16), + // Identifier is not unique + IdentifierNotUnique(String), } type ValidationResult = std::result::Result; @@ -256,6 +258,9 @@ impl fmt::Display for ValidationError { pci_segment ) } + IdentifierNotUnique(s) => { + write!(f, "Identifier {} is not unique", s) + } } } } @@ -2325,6 +2330,8 @@ pub struct VmConfig { impl VmConfig { // Also enables virtio-iommu if the config needs it pub fn validate(&mut self) -> ValidationResult<()> { + let mut id_list = BTreeSet::new(); + #[cfg(not(feature = "tdx"))] self.kernel.as_ref().ok_or(ValidationError::KernelMissing)?; @@ -2369,6 +2376,12 @@ impl VmConfig { } disk.validate(self)?; self.iommu |= disk.iommu; + + if let Some(id) = disk.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } } @@ -2379,6 +2392,12 @@ impl VmConfig { } net.validate(self)?; self.iommu |= net.iommu; + + if let Some(id) = net.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } } @@ -2388,6 +2407,12 @@ impl VmConfig { } for fs in fses { fs.validate(self)?; + + if let Some(id) = fs.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } } @@ -2395,6 +2420,12 @@ impl VmConfig { for pmem in pmems { pmem.validate(self)?; self.iommu |= pmem.iommu; + + if let Some(id) = pmem.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } } @@ -2440,6 +2471,12 @@ impl VmConfig { for user_device in user_devices { user_device.validate(self)?; + + if let Some(id) = user_device.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } } @@ -2447,6 +2484,12 @@ impl VmConfig { for vdpa_device in vdpa_devices { vdpa_device.validate(self)?; self.iommu |= vdpa_device.iommu; + + if let Some(id) = vdpa_device.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } } @@ -2471,12 +2514,24 @@ impl VmConfig { for device in devices { device.validate(self)?; self.iommu |= device.iommu; + + if let Some(id) = device.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } } if let Some(vsock) = &self.vsock { vsock.validate(self)?; self.iommu |= vsock.iommu; + + if let Some(id) = vsock.id.clone() { + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } } if let Some(numa) = &self.numa { @@ -2497,6 +2552,25 @@ impl VmConfig { } } + if let Some(zones) = &self.memory.zones { + for zone in zones.iter() { + let id = zone.id.clone(); + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } + } + + #[cfg(target_arch = "x86_64")] + if let Some(sgx_epcs) = &self.sgx_epc { + for sgx_epc in sgx_epcs.iter() { + let id = sgx_epc.id.clone(); + if !id_list.insert(id.clone()) { + return Err(ValidationError::IdentifierNotUnique(id)); + } + } + } + self.platform.as_ref().map(|p| p.validate()).transpose()?; self.iommu |= self .platform