Skip to content

Commit

Permalink
update: iovec len to u32
Browse files Browse the repository at this point in the history
Changing the type of IoVecBuffer's and IoVecBufferMut's len from usize
to u32 as the buffer size can only be up to 2^32 -1 bytes.

Signed-off-by: Marco Bellan <marcobll@amazon.com>
  • Loading branch information
MarcoROG committed Jan 19, 2024
1 parent 4c8d541 commit 86c62f4
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 36 deletions.
38 changes: 19 additions & 19 deletions src/vmm/src/devices/virtio/iovec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ pub struct IoVecBuffer {
// container of the memory regions included in this IO vector
vecs: IoVecVec,
// Total length of the IoVecBuffer
len: usize,
len: u32,
}

impl IoVecBuffer {
/// Create an `IoVecBuffer` from a `DescriptorChain`
pub fn from_descriptor_chain(head: DescriptorChain) -> Result<Self, IoVecError> {
let mut vecs = IoVecVec::new();
let mut len = 0usize;
let mut len = 0u32;

let mut next_descriptor = Some(head);
while let Some(desc) = next_descriptor {
Expand All @@ -68,7 +68,7 @@ impl IoVecBuffer {
iov_base,
iov_len: desc.len as size_t,
});
len += desc.len as usize;
len += desc.len;

next_descriptor = desc.next_descriptor();
}
Expand All @@ -77,7 +77,7 @@ impl IoVecBuffer {
}

/// Get the total length of the memory regions covered by this `IoVecBuffer`
pub(crate) fn len(&self) -> usize {
pub(crate) fn len(&self) -> u32 {
self.len
}

Expand Down Expand Up @@ -106,7 +106,7 @@ impl IoVecBuffer {
mut buf: &mut [u8],
offset: usize,
) -> Result<(), VolatileMemoryError> {
if offset < self.len() {
if offset < self.len().try_into().unwrap() {
let expected = buf.len();
let bytes_read = self.read_volatile_at(&mut buf, offset, expected)?;

Expand Down Expand Up @@ -188,14 +188,14 @@ pub struct IoVecBufferMut {
// container of the memory regions included in this IO vector
vecs: IoVecVec,
// Total length of the IoVecBufferMut
len: usize,
len: u32,
}

impl IoVecBufferMut {
/// Create an `IoVecBufferMut` from a `DescriptorChain`
pub fn from_descriptor_chain(head: DescriptorChain) -> Result<Self, IoVecError> {
let mut vecs = IoVecVec::new();
let mut len = 0usize;
let mut len = 0u32;

for desc in head {
if !desc.is_write_only() {
Expand All @@ -217,14 +217,14 @@ impl IoVecBufferMut {
iov_base,
iov_len: desc.len as size_t,
});
len += desc.len as usize;
len += desc.len;
}

Ok(Self { vecs, len })
}

/// Get the total length of the memory regions covered by this `IoVecBuffer`
pub(crate) fn len(&self) -> usize {
pub(crate) fn len(&self) -> u32 {
self.len
}

Expand All @@ -244,7 +244,7 @@ impl IoVecBufferMut {
mut buf: &[u8],
offset: usize,
) -> Result<(), VolatileMemoryError> {
if offset < self.len() {
if offset < self.len().try_into().unwrap() {
let expected = buf.len();
let bytes_written = self.write_volatile_at(&mut buf, offset, expected)?;

Expand Down Expand Up @@ -334,18 +334,18 @@ mod tests {
iov_len: buf.len(),
}]
.into(),
len: buf.len(),
len: buf.len().try_into().unwrap(),
}
}
}

impl<'a> From<Vec<&'a [u8]>> for IoVecBuffer {
fn from(buffer: Vec<&'a [u8]>) -> Self {
let mut len = 0;
let mut len = 0u32;
let vecs = buffer
.into_iter()
.map(|slice| {
len += slice.len();
len += TryInto::<u32>::try_into(slice.len()).unwrap();
iovec {
iov_base: slice.as_ptr() as *mut c_void,
iov_len: slice.len(),
Expand All @@ -365,7 +365,7 @@ mod tests {
iov_len: buf.len(),
}]
.into(),
len: buf.len(),
len: buf.len().try_into().unwrap(),
}
}
}
Expand Down Expand Up @@ -625,7 +625,7 @@ mod verification {
// >= 1.
const MAX_DESC_LENGTH: usize = 4;

fn create_iovecs(mem: *mut u8, size: usize) -> (IoVecVec, usize) {
fn create_iovecs(mem: *mut u8, size: u32) -> (IoVecVec, u32) {
let nr_descs: usize = kani::any_where(|&n| n <= MAX_DESC_LENGTH);
let mut vecs: Vec<iovec> = Vec::with_capacity(nr_descs);
let mut len = 0usize;
Expand All @@ -635,11 +635,11 @@ mod verification {
// mmap. The assumption, here, that the last address is within the memory object's
// bound substitutes these checks that `IoVecBuffer(Mut)::new() performs.`
let addr: usize = kani::any();
let iov_len: usize =
let iov_len: u32 =
kani::any_where(|&len| matches!(addr.checked_add(len), Some(x) if x <= size));
let iov_base = unsafe { mem.offset(addr.try_into().unwrap()) } as *mut c_void;

vecs.push(iovec { iov_base, iov_len });
vecs.push(iovec { iov_base, iov_len: iov_len as usize });
len += iov_len;
}

Expand Down Expand Up @@ -729,7 +729,7 @@ mod verification {
assert_eq!(
iov.read_volatile_at(&mut KaniBuffer(&mut buf), offset, GUEST_MEMORY_SIZE)
.unwrap(),
buf.len().min(iov.len().saturating_sub(offset))
buf.len().min(iov.len().try_into().unwrap().saturating_sub(offset))
);
}

Expand All @@ -755,7 +755,7 @@ mod verification {
iov_mut
.write_volatile_at(&mut KaniBuffer(&mut buf), offset, GUEST_MEMORY_SIZE)
.unwrap(),
buf.len().min(iov_mut.len().saturating_sub(offset))
buf.len().min(iov_mut.len().try_into().unwrap().saturating_sub(offset))
);
}
}
8 changes: 4 additions & 4 deletions src/vmm/src/devices/virtio/net/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ impl Net {

if let Some(ns) = mmds_ns {
if ns.is_mmds_frame(headers) {
let mut frame = vec![0u8; frame_iovec.len() - vnet_hdr_len()];
let mut frame = vec![0u8; frame_iovec.len() as usize - vnet_hdr_len()];
// Ok to unwrap here, because we are passing a buffer that has the exact size
// of the `IoVecBuffer` minus the VNET headers.
frame_iovec
Expand All @@ -472,7 +472,7 @@ impl Net {
METRICS.mmds.rx_accepted.inc();

// MMDS frames are not accounted by the rate limiter.
Self::rate_limiter_replenish_op(rate_limiter, frame_iovec.len() as u64);
Self::rate_limiter_replenish_op(rate_limiter, u64::from(frame_iovec.len()));

// MMDS consumed the frame.
return Ok(true);
Expand All @@ -492,7 +492,7 @@ impl Net {

match Self::write_tap(tap, frame_iovec) {
Ok(_) => {
let len = frame_iovec.len() as u64;
let len = u64::from(frame_iovec.len());
net_metrics.tx_bytes_count.add(len);
net_metrics.tx_packets_count.inc();
net_metrics.tx_count.inc();
Expand Down Expand Up @@ -603,7 +603,7 @@ impl Net {
continue;
}
};
if !Self::rate_limiter_consume_op(&mut self.tx_rate_limiter, buffer.len() as u64) {
if !Self::rate_limiter_consume_op(&mut self.tx_rate_limiter, u64::from(buffer.len())) {
tx_queue.undo_pop();
self.metrics.tx_rate_limiter_throttled.inc();
break;
Expand Down
2 changes: 1 addition & 1 deletion src/vmm/src/devices/virtio/net/tap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ pub mod tests {

tap.write_iovec(&scattered).unwrap();

let mut read_buf = vec![0u8; scattered.len()];
let mut read_buf = vec![0u8; scattered.len() as usize];
assert!(tap_traffic_simulator.pop_rx_packet(&mut read_buf));
assert_eq!(
&read_buf[..PAYLOAD_SIZE - VNET_HDR_SIZE],
Expand Down
6 changes: 3 additions & 3 deletions src/vmm/src/devices/virtio/rng/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,15 @@ impl Entropy {
return Ok(0);
}

let mut rand_bytes = vec![0; iovec.len()];
let mut rand_bytes = vec![0; iovec.len().try_into().unwrap()];
rand::fill(&mut rand_bytes).map_err(|err| {
METRICS.host_rng_fails.inc();
err
})?;

// It is ok to unwrap here. We are writing `iovec.len()` bytes at offset 0.
iovec.write_all_volatile_at(&rand_bytes, 0).unwrap();
Ok(iovec.len().try_into().unwrap())
Ok(iovec.len())
}

fn process_entropy_queue(&mut self) {
Expand All @@ -142,7 +142,7 @@ impl Entropy {
// Check for available rate limiting budget.
// If not enough budget is available, leave the request descriptor in the queue
// to handle once we do have budget.
if !Self::rate_limit_request(&mut self.rate_limiter, iovec.len() as u64) {
if !Self::rate_limit_request(&mut self.rate_limiter, u64::from(iovec.len())) {
debug!("entropy: throttling entropy queue");
METRICS.entropy_rate_limiter_throttled.inc();
self.queues[RNG_QUEUE].undo_pop();
Expand Down
16 changes: 7 additions & 9 deletions src/vmm/src/devices/virtio/vsock/packet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,9 @@ impl VsockPacket {
return Err(VsockError::InvalidPktLen(hdr.len));
}

if (hdr.len as usize) > buffer.len() - VSOCK_PKT_HDR_SIZE as usize {
if hdr.len > buffer.len() - VSOCK_PKT_HDR_SIZE {
return Err(VsockError::DescChainTooShortForPacket(
buffer.len(),
buffer.len() as usize,
hdr.len,
));
}
Expand All @@ -160,8 +160,8 @@ impl VsockPacket {
pub fn from_rx_virtq_head(chain: DescriptorChain) -> Result<Self, VsockError> {
let buffer = IoVecBufferMut::from_descriptor_chain(chain)?;

if buffer.len() < VSOCK_PKT_HDR_SIZE as usize {
return Err(VsockError::DescChainTooShortForHeader(buffer.len()));
if buffer.len() < VSOCK_PKT_HDR_SIZE {
return Err(VsockError::DescChainTooShortForHeader(buffer.len() as usize));
}

Ok(Self {
Expand Down Expand Up @@ -212,7 +212,7 @@ impl VsockPacket {
VsockPacketBuffer::Tx(ref iovec_buf) => iovec_buf.len(),
VsockPacketBuffer::Rx(ref iovec_buf) => iovec_buf.len(),
};
chain_length - VSOCK_PKT_HDR_SIZE as usize
(chain_length - VSOCK_PKT_HDR_SIZE) as usize
}

pub fn read_at_offset_from<T: ReadVolatile + Debug>(
Expand All @@ -225,8 +225,7 @@ impl VsockPacket {
VsockPacketBuffer::Tx(_) => Err(VsockError::UnwritableDescriptor),
VsockPacketBuffer::Rx(ref mut buffer) => {
if count
> buffer
.len()
> (buffer.len() as usize)
.saturating_sub(VSOCK_PKT_HDR_SIZE as usize)
.saturating_sub(offset)
{
Expand All @@ -249,8 +248,7 @@ impl VsockPacket {
match self.buffer {
VsockPacketBuffer::Tx(ref buffer) => {
if count
> buffer
.len()
> (buffer.len() as usize)
.saturating_sub(VSOCK_PKT_HDR_SIZE as usize)
.saturating_sub(offset)
{
Expand Down

0 comments on commit 86c62f4

Please sign in to comment.