Skip to content

Commit 23342b1

Browse files
committed
refactor(queue): safer write_used_ring method
Now `write_used_ring` makes sure the index is in correct bounds. This way there is no way for a caller to provide index outside of bounds. Signed-off-by: Egor Lazarchuk <[email protected]>
1 parent 3cedad8 commit 23342b1

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

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

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -446,12 +446,11 @@ impl Queue {
446446
) -> Result<(), QueueError> {
447447
debug_assert!(self.is_layout_valid(mem));
448448

449-
let next_used = self.next_used.0 % self.actual_size();
450449
let used_element = UsedElement {
451450
id: u32::from(desc_index),
452451
len,
453452
};
454-
self.write_used_ring(mem, next_used, used_element)?;
453+
self.write_used_ring(mem, self.next_used.0, used_element)?;
455454
self.advance_used_ring(mem, 1);
456455
Ok(())
457456
}
@@ -491,11 +490,14 @@ impl Queue {
491490
// We calculate offset into `ring` field.
492491
let used_ring_offset = std::mem::size_of::<u16>()
493492
+ std::mem::size_of::<u16>()
494-
+ std::mem::size_of::<UsedElement>() * usize::from(index);
493+
+ std::mem::size_of::<UsedElement>() * usize::from(index % self.actual_size());
495494
let used_element_address = self.used_ring.unchecked_add(usize_to_u64(used_ring_offset));
496495

497-
mem.write_obj(used_element, used_element_address)
498-
.map_err(QueueError::UsedRing)
496+
// SAFETY:
497+
// `used_element_address` param is bounded by size of the queue as `index` is
498+
// modded by `actual_size()`.
499+
mem.write_obj(used_element, used_element_address).unwrap();
500+
Ok(())
499501
}
500502

501503
/// Fetch the available ring index (`virtq_avail->idx`) from guest memory.

0 commit comments

Comments
 (0)