vmm: validate host data for SevSnp guest

Host data for SevSnp guest should either be empty
or 64 character hex value.

Signed-off-by: Muminul Islam <muislam@microsoft.com>
This commit is contained in:
Muminul Islam 2024-02-14 17:22:17 -08:00 committed by Bo Chen
parent aa6c486a6b
commit e51fb0ee36

View File

@ -193,6 +193,8 @@ pub enum ValidationError {
/// The specified I/O port was invalid. It should be provided in hex, such as `0xe9`. /// The specified I/O port was invalid. It should be provided in hex, such as `0xe9`.
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
InvalidIoPortHex(String), InvalidIoPortHex(String),
#[cfg(feature = "sev_snp")]
InvalidHostData,
} }
type ValidationResult<T> = std::result::Result<T, ValidationError>; type ValidationResult<T> = std::result::Result<T, ValidationError>;
@ -328,6 +330,10 @@ impl fmt::Display for ValidationError {
"The IO port was not properly provided in hex or a `0x` prefix is missing: {s}" "The IO port was not properly provided in hex or a `0x` prefix is missing: {s}"
) )
} }
#[cfg(feature = "sev_snp")]
InvalidHostData => {
write!(f, "Invalid host data format")
}
} }
} }
} }
@ -2143,6 +2149,16 @@ impl VmConfig {
} }
} }
#[cfg(feature = "sev_snp")]
{
let host_data_opt = &self.payload.as_ref().unwrap().host_data;
if let Some(host_data) = host_data_opt {
if host_data.len() != 64 {
return Err(ValidationError::InvalidHostData);
}
}
}
// The 'conflict' check is introduced in commit 24438e0390d3 // The 'conflict' check is introduced in commit 24438e0390d3
// (vm-virtio: Enable the vmm support for virtio-console). // (vm-virtio: Enable the vmm support for virtio-console).
// //
@ -3461,7 +3477,9 @@ mod tests {
#[cfg(feature = "igvm")] #[cfg(feature = "igvm")]
igvm: None, igvm: None,
#[cfg(feature = "sev_snp")] #[cfg(feature = "sev_snp")]
host_data: None, host_data: Some(
"243eb7dc1a21129caa91dcbb794922b933baecb5823a377eb431188673288c07".to_string(),
),
}), }),
rate_limit_groups: None, rate_limit_groups: None,
disks: None, disks: None,
@ -3979,6 +3997,52 @@ mod tests {
}, },
]); ]);
assert!(invalid_config.validate().is_err()); assert!(invalid_config.validate().is_err());
#[cfg(feature = "sev_snp")]
{
// Payload with empty host data
let mut config_with_no_host_data = valid_config.clone();
config_with_no_host_data.payload = Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
firmware: None,
cmdline: None,
initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
#[cfg(feature = "sev_snp")]
host_data: Some("".to_string()),
});
assert!(config_with_no_host_data.validate().is_err());
// Payload with no host data provided
let mut valid_config_with_no_host_data = valid_config.clone();
valid_config_with_no_host_data.payload = Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
firmware: None,
cmdline: None,
initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
#[cfg(feature = "sev_snp")]
host_data: None,
});
assert!(valid_config_with_no_host_data.validate().is_ok());
// Payload with invalid host data length i.e less than 64
let mut config_with_invalid_host_data = valid_config.clone();
config_with_invalid_host_data.payload = Some(PayloadConfig {
kernel: Some(PathBuf::from("/path/to/kernel")),
firmware: None,
cmdline: None,
initramfs: None,
#[cfg(feature = "igvm")]
igvm: None,
#[cfg(feature = "sev_snp")]
host_data: Some(
"243eb7dc1a21129caa91dcbb794922b933baecb5823a377eb43118867328".to_string(),
),
});
assert!(config_with_invalid_host_data.validate().is_err());
}
let mut still_valid_config = valid_config; let mut still_valid_config = valid_config;
// SAFETY: Safe as the file was just opened // SAFETY: Safe as the file was just opened