Skip to content

Commit f083fe6

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 f083fe6

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -257,19 +257,29 @@ impl VirtioPciCommonConfig {
257257

258258
fn write_common_config_word(&mut self, offset: u64, value: u16, queues: &mut [Queue]) {
259259
match offset {
260-
0x10 => self.msix_config.store(value, Ordering::Release),
260+
0x10 => {
261+
let mut msix_queues = self.msix_queues.lock().expect("Poisoned lock");
262+
let nr_vectors = msix_queues.len() + 1;
263+
264+
if (value as usize) < nr_vectors {
265+
self.msix_config.store(value, Ordering::Release);
266+
} else {
267+
self.msix_config.store(0xffff, Ordering::Release);
268+
}
269+
}
261270
0x16 => self.queue_select = value,
262271
0x18 => self.with_queue_mut(queues, |q| q.size = value),
263272
0x1a => {
273+
let mut msix_queues = self.msix_queues.lock().expect("Poisoned lock");
274+
let nr_vectors = msix_queues.len() + 1;
264275
// Make sure that `queue_select` points to a valid queue. If not, we won't do
265276
// 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;
277+
if let Some(queue) = msix_queues.get_mut(self.queue_select as usize) {
278+
if (value as usize) < nr_vectors {
279+
*queue = value;
280+
} else {
281+
*queue = 0xffff;
282+
}
273283
}
274284
}
275285
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)