mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: iommu: Validate ATTACH reserved field and flags
The virtio spec requires the device to reject ATTACH with a non-zero reserved field, an unknown flag bit, or a bypass flag that conflicts with an existing domain. The current handler silently accepts all three. Signed-off-by: Rob Bradford <rbradford@meta.com> Assisted-by: Claude:claude-opus-4-7
This commit is contained in:
@@ -150,7 +150,7 @@ struct VirtioIommuReqAttach {
|
||||
domain: u32,
|
||||
endpoint: u32,
|
||||
flags: u32,
|
||||
_reserved: [u8; 4],
|
||||
reserved: [u8; 4],
|
||||
}
|
||||
|
||||
const VIRTIO_IOMMU_ATTACH_F_BYPASS: u32 = 1;
|
||||
@@ -404,12 +404,26 @@ impl Request {
|
||||
.map_err(Error::GuestMemory)?;
|
||||
debug!("Attach request 0x{req:x?}");
|
||||
|
||||
if req.reserved.iter().any(|&b| b != 0)
|
||||
|| (req.flags & !VIRTIO_IOMMU_ATTACH_F_BYPASS) != 0
|
||||
{
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidAttachRequest);
|
||||
}
|
||||
|
||||
// Copy the value to use it as a proper reference.
|
||||
let domain_id = req.domain;
|
||||
let endpoint = req.endpoint;
|
||||
let bypass =
|
||||
(req.flags & VIRTIO_IOMMU_ATTACH_F_BYPASS) == VIRTIO_IOMMU_ATTACH_F_BYPASS;
|
||||
|
||||
if let Some(d) = mapping.domains.read().unwrap().get(&domain_id)
|
||||
&& d.bypass != bypass
|
||||
{
|
||||
status = VIRTIO_IOMMU_S_INVAL;
|
||||
return Err(Error::InvalidAttachRequest);
|
||||
}
|
||||
|
||||
let mut old_domain_id = domain_id;
|
||||
if let Some(&id) = mapping.endpoints.read().unwrap().get(&endpoint) {
|
||||
old_domain_id = id;
|
||||
|
||||
Reference in New Issue
Block a user