mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-01 17:35:19 +00:00
virtio-devices: rng: Error out of queue execution on invalid requests
With the virtio-rng device the descriptors that are provided by the guest must be writable and of non-zero length. Also propagate an error if writing to the guest memory fails. Signed-off-by: Bo Chen <chen.bo@intel.com>
This commit is contained in:
parent
4779265453
commit
f0c55f5245
@ -40,6 +40,10 @@ const QUEUE_AVAIL_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 1;
|
|||||||
enum Error {
|
enum Error {
|
||||||
#[error("Descriptor chain too short")]
|
#[error("Descriptor chain too short")]
|
||||||
DescriptorChainTooShort,
|
DescriptorChainTooShort,
|
||||||
|
#[error("Invalid descriptor")]
|
||||||
|
InvalidDescriptor,
|
||||||
|
#[error("Failed read from guest memory: {0}")]
|
||||||
|
GuestMemoryRead(vm_memory::guest_memory::Error),
|
||||||
#[error("Failed adding used index: {0}")]
|
#[error("Failed adding used index: {0}")]
|
||||||
QueueAddUsed(virtio_queue::Error),
|
QueueAddUsed(virtio_queue::Error),
|
||||||
}
|
}
|
||||||
@ -62,23 +66,25 @@ impl RngEpollHandler {
|
|||||||
let mut used_descs = false;
|
let mut used_descs = false;
|
||||||
while let Some(mut desc_chain) = queue.pop_descriptor_chain(self.mem.memory()) {
|
while let Some(mut desc_chain) = queue.pop_descriptor_chain(self.mem.memory()) {
|
||||||
let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
|
let desc = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
|
||||||
let mut len = 0;
|
|
||||||
|
|
||||||
// Drivers can only read from the random device.
|
// The descriptor must be write-only and non-zero length
|
||||||
if desc.is_write_only() {
|
if !(desc.is_write_only() && desc.len() > 0) {
|
||||||
// Fill the read with data from the random device on the host.
|
return Err(Error::InvalidDescriptor);
|
||||||
if let Ok(number_of_bytes) = desc_chain.memory().read_from(
|
}
|
||||||
|
|
||||||
|
// Fill the read with data from the random device on the host.
|
||||||
|
let len = desc_chain
|
||||||
|
.memory()
|
||||||
|
.read_from(
|
||||||
desc.addr()
|
desc.addr()
|
||||||
.translate_gva(self.access_platform.as_ref(), desc.len() as usize),
|
.translate_gva(self.access_platform.as_ref(), desc.len() as usize),
|
||||||
&mut self.random_file,
|
&mut self.random_file,
|
||||||
desc.len() as usize,
|
desc.len() as usize,
|
||||||
) {
|
)
|
||||||
len = number_of_bytes as u32;
|
.map_err(Error::GuestMemoryRead)?;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
queue
|
queue
|
||||||
.add_used(desc_chain.memory(), desc_chain.head_index(), len)
|
.add_used(desc_chain.memory(), desc_chain.head_index(), len as u32)
|
||||||
.map_err(Error::QueueAddUsed)?;
|
.map_err(Error::QueueAddUsed)?;
|
||||||
used_descs = true;
|
used_descs = true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user