diff --git a/vm/devices/virtio/virtio/src/queue.rs b/vm/devices/virtio/virtio/src/queue.rs index 959bd5107e..12a8fc6f2f 100644 --- a/vm/devices/virtio/virtio/src/queue.rs +++ b/vm/devices/virtio/virtio/src/queue.rs @@ -62,6 +62,8 @@ pub enum QueueError { TooLong, #[error("Invalid queue size {0}. Must be a power of 2.")] InvalidQueueSize(u16), + #[error("descriptor index {0} is out of range")] + InvalidDescriptorIndex(u16), } pub struct QueueDescriptor { diff --git a/vm/devices/virtio/virtio/src/queue/split.rs b/vm/devices/virtio/virtio/src/queue/split.rs index 447c9eee8e..798a7220dd 100644 --- a/vm/devices/virtio/virtio/src/queue/split.rs +++ b/vm/devices/virtio/virtio/src/queue/split.rs @@ -117,13 +117,17 @@ impl SplitQueueGetWork { } pub fn get_available_descriptor_index(&self, wrapped_index: u16) -> Result { - Ok(self + let desc_index = self .queue_avail .read_plain::( spec::AVAIL_OFFSET_RING + spec::AVAIL_ELEMENT_SIZE * wrapped_index as u64, ) .map_err(QueueError::Memory)? - .get()) + .get(); + if desc_index >= self.queue_size { + return Err(QueueError::InvalidDescriptorIndex(desc_index)); + } + Ok(desc_index) } fn set_available_event(&self, index: u16) -> Result<(), QueueError> {