Skip to content

Commit 1099a06

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 e0f3828 commit 1099a06

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
@@ -450,12 +450,11 @@ impl Queue {
450450
) -> Result<(), QueueError> {
451451
debug_assert!(self.is_layout_valid(mem));
452452

453-
let next_used = self.next_used.0 % self.actual_size();
454453
let used_element = UsedElement {
455454
id: u32::from(desc_index),
456455
len,
457456
};
458-
self.write_used_ring(mem, next_used, used_element)?;
457+
self.write_used_ring(mem, self.next_used.0, used_element)?;
459458
self.advance_used_ring(mem, 1);
460459
Ok(())
461460
}
@@ -495,11 +494,14 @@ impl Queue {
495494
// We calculate offset into `ring` field.
496495
let used_ring_offset = std::mem::size_of::<u16>()
497496
+ std::mem::size_of::<u16>()
498-
+ std::mem::size_of::<UsedElement>() * usize::from(index);
497+
+ std::mem::size_of::<UsedElement>() * usize::from(index % self.actual_size());
499498
let used_element_address = self.used_ring.unchecked_add(usize_to_u64(used_ring_offset));
500499

501-
mem.write_obj(used_element, used_element_address)
502-
.map_err(QueueError::UsedRing)
500+
// SAFETY:
501+
// `used_element_address` param is bounded by size of the queue as `index` is
502+
// modded by `actual_size()`.
503+
mem.write_obj(used_element, used_element_address).unwrap();
504+
Ok(())
503505
}
504506

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

0 commit comments

Comments
 (0)