virtio-devices: mem: Validate descriptor ranges

Add check_range calls on request and status descriptor addresses to
reject buffers that extend past guest memory.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-05-13 16:30:34 +02:00
committed by Rob Bradford
parent 661b9dee8f
commit 795e606183

View File

@@ -30,7 +30,7 @@ use thiserror::Error;
use virtio_queue::{DescriptorChain, Queue, QueueT};
use vm_device::dma_mapping::ExternalDmaMapping;
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemoryAtomic,
Address, ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic,
GuestMemoryError, GuestMemoryLoadGuard, GuestMemoryRegion,
};
use vm_migration::protocol::MemoryRangeTable;
@@ -284,6 +284,14 @@ impl Request {
if (desc.len() as usize) < size_of::<VirtioMemReq>() {
return Err(Error::InvalidRequest);
}
if !desc_chain
.memory()
.check_range(desc.addr(), desc.len() as usize)
{
return Err(Error::GuestMemory(GuestMemoryError::InvalidGuestAddress(
desc.addr(),
)));
}
let req: VirtioMemReq = desc_chain
.memory()
.read_obj(desc.addr())
@@ -300,6 +308,15 @@ impl Request {
return Err(Error::BufferLengthTooSmall);
}
if !desc_chain
.memory()
.check_range(status_desc.addr(), status_desc.len() as usize)
{
return Err(Error::GuestMemory(GuestMemoryError::InvalidGuestAddress(
status_desc.addr(),
)));
}
Ok(Request {
req,
status_addr: status_desc.addr(),