Skip to content

Commit 130eee5

Browse files
committed
chore(vmm): Add pointer alignment check for Queue
read_volatile() method is called on avail_ring_ptr and used_ring_ptr of Queue and it assumes a pointer of interest is aligned properly; otherwise results in a panic. Such an unalignment is possible when restored from a broken/fuzzed snapshot. Both must be aligned at least for u16 (2-byte alignment) as documented in Queue. Add pointer alignment check and exit with an error instead of panic. Signed-off-by: Takahiro Itazuri <[email protected]>
1 parent 5b706ed commit 130eee5

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

src/vmm/src/devices/virtio/queue.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ pub enum QueueError {
3434
DescIndexOutOfBounds(u16),
3535
/// Failed to write value into the virtio queue used ring: {0}
3636
MemoryError(#[from] vm_memory::GuestMemoryError),
37+
/// Pointer is not aligned properly: {0}
38+
PointerNotAligned(String),
3739
}
3840

3941
/// A virtio descriptor constraints with C representative.
@@ -323,6 +325,20 @@ impl Queue {
323325
.get_slice_ptr(mem, self.used_ring_address, self.used_ring_size())?
324326
.cast();
325327

328+
// read_volatile() method is called on avail_ring_ptr and used_ring_ptr and it assumes that
329+
// a pointer of interest is aligned properly; otherwise results in a panic. Such an
330+
// unalignment is possible when restored from a broken/fuzzed snapshot. Both
331+
// `avail_ring_ptr` and `used_ring_ptr` must be aligned at least for u16 (2-byte alignment)
332+
// as documented in `struct Queue`.
333+
if !self.avail_ring_ptr.is_aligned() {
334+
return Err(QueueError::PointerNotAligned(
335+
"Queue::avail_ring_ptr".into(),
336+
));
337+
}
338+
if !self.used_ring_ptr.cast::<u16>().is_aligned() {
339+
return Err(QueueError::PointerNotAligned("Queue::used_ring_ptr".into()));
340+
}
341+
326342
// Disable it for kani tests, otherwise it will hit this assertion
327343
// and fail.
328344
#[cfg(not(kani))]

0 commit comments

Comments
 (0)