virtio-devices: rng: Use checked descriptor iterator

Replace manual translate_gva call with checked_iter which validates
the descriptor buffer range against guest memory before I/O.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-05-13 14:29:05 +02:00
committed by Rob Bradford
parent 4c6d60f162
commit 45cba34101

View File

@@ -19,7 +19,8 @@ use thiserror::Error;
use virtio_queue::{Queue, QueueT};
use vm_memory::{Bytes, GuestAddressSpace, GuestMemoryAtomic};
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::{
@@ -61,26 +62,25 @@ impl RngEpollHandler {
let mut used_descs = false;
while let Some(mut desc_chain) = queue.pop_descriptor_chain(self.mem.memory()) {
let mut total_len: usize = 0;
while let Some(desc) = desc_chain.next() {
// Validate the entire descriptor chain upfront so we never
// partially fill buffers for a chain that turns out to be
// invalid.
let descs: Vec<_> = desc_chain
.checked_iter(self.access_platform.as_deref())
.collect::<Result<_, _>>()
.unwrap_or_default();
for desc in &descs {
if !desc.is_write_only() {
warn!("Skipping device-readable descriptor");
continue;
}
if desc.len() == 0 {
if desc.is_empty() {
continue;
}
let addr = match desc
.addr()
.translate_gva(self.access_platform.as_deref(), desc.len() as usize)
{
Ok(a) => a,
Err(e) => {
warn!("Failed to translate descriptor address: {e}");
break;
}
};
match desc_chain.memory().read_volatile_from(
addr,
desc.addr(),
&mut self.random_file,
desc.len() as usize,
) {