vmm: forbid using special VSOCK CIDs for guests

I accidentally ran a VM with CID 2 (VMADDR_CID_HOST), and very strange
and difficult to debug behavior ensued.  I don't think a virtio-vsock
device should be allowed to have any of the special CIDs
(VMADDR_CID_ANY, VMADDR_CID_HYPERVISOR, VMADDR_CID_LOCAL, VMADDR_CID_HOST).

Signed-off-by: Alyssa Ross <hi@alyssa.is>
This commit is contained in:
Alyssa Ross 2024-01-05 12:21:50 +01:00 committed by Rob Bradford
parent 5857d8a7cc
commit 7d0b85d727
2 changed files with 22 additions and 7 deletions

View File

@ -155,6 +155,8 @@ pub enum ValidationError {
TooManyQueues,
/// Need shared memory for vfio-user
UserDevicesRequireSharedMemory,
/// VSOCK Context Identifier has a special meaning, unsuitable for a VM.
VsockSpecialCid(u64),
/// Memory zone is reused across NUMA nodes
MemoryZoneReused(String, u32, u32),
/// Invalid number of PCI segments
@ -245,6 +247,9 @@ impl fmt::Display for ValidationError {
"Using user devices requires using shared memory or huge pages"
)
}
VsockSpecialCid(cid) => {
write!(f, "{cid} is a special VSOCK CID")
}
MemoryZoneReused(s, u1, u2) => {
write!(
f,
@ -2193,6 +2198,12 @@ impl VmConfig {
}
}
if let Some(vsock) = &self.vsock {
if [u32::MAX as u64, 0, 1, 2].contains(&vsock.cid) {
return Err(ValidationError::VsockSpecialCid(vsock.cid));
}
}
if let Some(balloon) = &self.balloon {
let mut ram_size = self.memory.size;
@ -3222,9 +3233,9 @@ mod tests {
// socket and cid is required
assert!(VsockConfig::parse("").is_err());
assert_eq!(
VsockConfig::parse("socket=/tmp/sock,cid=1")?,
VsockConfig::parse("socket=/tmp/sock,cid=3")?,
VsockConfig {
cid: 1,
cid: 3,
socket: PathBuf::from("/tmp/sock"),
iommu: false,
id: None,
@ -3232,9 +3243,9 @@ mod tests {
}
);
assert_eq!(
VsockConfig::parse("socket=/tmp/sock,cid=1,iommu=on")?,
VsockConfig::parse("socket=/tmp/sock,cid=3,iommu=on")?,
VsockConfig {
cid: 1,
cid: 3,
socket: PathBuf::from("/tmp/sock"),
iommu: true,
id: None,
@ -3568,9 +3579,11 @@ mod tests {
..Default::default()
});
still_valid_config.vsock = Some(VsockConfig {
cid: 3,
socket: PathBuf::new(),
id: None,
iommu: true,
pci_segment: 1,
..Default::default()
});
assert!(still_valid_config.validate().is_ok());
@ -3645,9 +3658,11 @@ mod tests {
..Default::default()
});
invalid_config.vsock = Some(VsockConfig {
cid: 3,
socket: PathBuf::new(),
id: None,
iommu: false,
pci_segment: 1,
..Default::default()
});
assert_eq!(
invalid_config.validate(),

View File

@ -2673,7 +2673,7 @@ mod unit_tests {
#[test]
fn test_vmm_vm_cold_add_vsock() {
let mut vmm = create_dummy_vmm();
let vsock_config = VsockConfig::parse("socket=/tmp/sock,cid=1,iommu=on").unwrap();
let vsock_config = VsockConfig::parse("socket=/tmp/sock,cid=3,iommu=on").unwrap();
assert!(matches!(
vmm.vm_add_vsock(vsock_config.clone()),