diff --git a/vm-migration/src/protocol.rs b/vm-migration/src/protocol.rs index 3ae226ece..4dfec4f62 100644 --- a/vm-migration/src/protocol.rs +++ b/vm-migration/src/protocol.rs @@ -332,19 +332,19 @@ impl MemoryRangeTable { pub fn read_from(fd: &mut dyn Read, length: u64) -> Result { assert!((length as usize).is_multiple_of(size_of::())); - let mut data: Vec = Vec::new(); - data.resize_with( - length as usize / (std::mem::size_of::()), - Default::default, - ); - // SAFETY: the slice is constructed with the correct arguments - fd.read_exact(unsafe { - std::slice::from_raw_parts_mut( - data.as_ptr() as *mut MemoryRange as *mut u8, - length as usize, - ) - }) - .map_err(MigratableError::MigrateSocket)?; + let mut data: Vec = + vec![MemoryRange::default(); length as usize / size_of::()]; + + // SAFETY: The pointer points to the just created vector data. + // `MemoryRange` can be read from and written to bytes since it's `[repr(C)]`. + // The vector data was initialized with `length as usize / size_of::()` valid + // `MemoryRange`s so the memory is valid for `length` bytes. + // During the lifetime of the slice, neither the backing vector nor the pointed to memory are accessed. + let data_slice_bytes = + unsafe { std::slice::from_raw_parts_mut(data.as_mut_ptr().cast(), length as usize) }; + + fd.read_exact(data_slice_bytes) + .map_err(MigratableError::MigrateSocket)?; Ok(Self { data }) }