From 661b9dee8fec4d53072fde82cf92a8e8af090ec4 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 13 May 2026 16:25:16 +0200 Subject: [PATCH] virtio-devices: pmem: Use checked descriptor iterator Replace inline translate_gva and check_range with checked_iter, which validates the descriptor buffer range against guest memory before yielding each descriptor. Signed-off-by: Anatol Belski --- virtio-devices/src/pmem.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/virtio-devices/src/pmem.rs b/virtio-devices/src/pmem.rs index 2c5c2538c..b4ef559f5 100644 --- a/virtio-devices/src/pmem.rs +++ b/virtio-devices/src/pmem.rs @@ -26,7 +26,8 @@ use vm_memory::{ GuestMemoryError, GuestMemoryLoadGuard, }; use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; -use vm_virtio::{AccessPlatform, Translatable}; +use vm_virtio::AccessPlatform; +use vm_virtio::checked_descriptor::DescriptorChainExt; use vmm_sys_util::eventfd::EventFd; use super::{ @@ -110,7 +111,10 @@ impl Request { desc_chain: &mut DescriptorChain>, access_platform: Option<&dyn AccessPlatform>, ) -> result::Result { - let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?; + let desc = desc_chain + .next_checked(access_platform) + .map_err(|addr| Error::GuestMemory(GuestMemoryError::InvalidGuestAddress(addr)))? + .ok_or(Error::DescriptorChainTooShort)?; // The descriptor contains the request type which MUST be readable. if desc.is_write_only() { return Err(Error::UnexpectedWriteOnlyDescriptor); @@ -122,11 +126,7 @@ impl Request { let request: VirtioPmemReq = desc_chain .memory() - .read_obj( - desc.addr() - .translate_gva(access_platform, desc.len() as usize) - .map_err(|e| Error::GuestMemory(GuestMemoryError::IOError(e)))?, - ) + .read_obj(desc.addr()) .map_err(Error::GuestMemory)?; let request_type = match request.type_ { @@ -134,7 +134,10 @@ impl Request { t => RequestType::Unknown(t), }; - let status_desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?; + let status_desc = desc_chain + .next_checked(access_platform) + .map_err(|addr| Error::GuestMemory(GuestMemoryError::InvalidGuestAddress(addr)))? + .ok_or(Error::DescriptorChainTooShort)?; // The status MUST always be writable if !status_desc.is_write_only() { @@ -147,10 +150,7 @@ impl Request { Ok(Request { type_: request_type, - status_addr: status_desc - .addr() - .translate_gva(access_platform, status_desc.len() as usize) - .map_err(|e| Error::GuestMemory(GuestMemoryError::IOError(e)))?, + status_addr: status_desc.addr(), }) } }