Skip to content

Commit 874ffb1

Browse files
committed
fix(virtio-pci): check guest values for MSI-X vector
We should check that the MSI-X vector that a guest assigns to a VirtIO queue or configuration is a valid one. If it is a value bigger than the available vectors allocated for the device, it should not update the vector field and mark the corresponding vector to the NO_VECTOR value. Signed-off-by: Babis Chalios <[email protected]>
1 parent 060ab3b commit 874ffb1

File tree

2 files changed

+20
-14
lines changed

2 files changed

+20
-14
lines changed

src/vmm/src/devices/virtio/transport/pci/common_config.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -261,15 +261,16 @@ impl VirtioPciCommonConfig {
261261
0x16 => self.queue_select = value,
262262
0x18 => self.with_queue_mut(queues, |q| q.size = value),
263263
0x1a => {
264+
let mut msix_queues = self.msix_queues.lock().expect("Poisoned lock");
265+
let nr_vectors = msix_queues.len() + 1;
264266
// Make sure that `queue_select` points to a valid queue. If not, we won't do
265267
// anything here and subsequent reads at 0x1a will return `NO_VECTOR`.
266-
if let Some(msix_queue) = self
267-
.msix_queues
268-
.lock()
269-
.unwrap()
270-
.get_mut(self.queue_select as usize)
271-
{
272-
*msix_queue = value;
268+
if let Some(queue) = msix_queues.get_mut(self.queue_select as usize) {
269+
if (value as usize) < nr_vectors {
270+
*queue = value;
271+
} else {
272+
*queue = 0xffff;
273+
}
273274
}
274275
}
275276
0x1c => self.with_queue_mut(queues, |q| {

src/vmm/src/devices/virtio/transport/pci/device.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use std::cmp;
1111
use std::collections::HashMap;
1212
use std::fmt::{Debug, Formatter};
13-
use std::io::Write;
13+
use std::io::{ErrorKind, Write};
1414
use std::sync::atomic::{AtomicBool, AtomicU16, AtomicU32, AtomicUsize, Ordering};
1515
use std::sync::{Arc, Barrier, Mutex};
1616

@@ -764,9 +764,12 @@ impl VirtioInterrupt for VirtioInterruptMsix {
764764
fn trigger(&self, int_type: VirtioInterruptType) -> std::result::Result<(), std::io::Error> {
765765
let vector = match int_type {
766766
VirtioInterruptType::Config => self.config_vector.load(Ordering::Acquire),
767-
VirtioInterruptType::Queue(queue_index) => {
768-
self.queues_vectors.lock().unwrap()[queue_index as usize]
769-
}
767+
VirtioInterruptType::Queue(queue_index) => *self
768+
.queues_vectors
769+
.lock()
770+
.unwrap()
771+
.get(queue_index as usize)
772+
.ok_or(ErrorKind::InvalidInput)?,
770773
};
771774

772775
if vector == VIRTQ_MSI_NO_VECTOR {
@@ -792,9 +795,11 @@ impl VirtioInterrupt for VirtioInterruptMsix {
792795
fn notifier(&self, int_type: VirtioInterruptType) -> Option<&EventFd> {
793796
let vector = match int_type {
794797
VirtioInterruptType::Config => self.config_vector.load(Ordering::Acquire),
795-
VirtioInterruptType::Queue(queue_index) => {
796-
self.queues_vectors.lock().unwrap()[queue_index as usize]
797-
}
798+
VirtioInterruptType::Queue(queue_index) => *self
799+
.queues_vectors
800+
.lock()
801+
.unwrap()
802+
.get(queue_index as usize)?,
798803
};
799804

800805
self.interrupt_source_group

0 commit comments

Comments
 (0)