Skip to content

Commit ff92a97

Browse files
JBYoshiJonathanWoollett-Light
authored andcommitted
Add a u64_to_usize function for safe conversions
Clippy warns about conversions from u64 to usize types because they may break on 32-bit systems. However, Firecracker only supports 64-bit systems, so they're safe in our case. To minimize the number of places we need to suppress the Clippy warning, I've extracted those to a single function. Signed-off-by: Jonathan Browne <[email protected]>
1 parent 00853d6 commit ff92a97

File tree

16 files changed

+45
-21
lines changed

16 files changed

+45
-21
lines changed

src/rebase-snap/src/main.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::os::unix::io::AsRawFd;
88

99
use utils::arg_parser::{ArgParser, Argument, Arguments, Error as ArgError};
1010
use utils::seek_hole::SeekHole;
11+
use utils::u64_to_usize;
1112

1213
const REBASE_SNAP_VERSION: &str = env!("CARGO_PKG_VERSION");
1314
const BASE_FILE: &str = "base-file";
@@ -101,7 +102,7 @@ fn rebase(base_file: &mut File, diff_file: &mut File) -> Result<(), FileError> {
101102
base_file.as_raw_fd(),
102103
diff_file.as_raw_fd(),
103104
(&mut cursor as *mut u64).cast::<i64>(),
104-
block_end.saturating_sub(cursor) as usize,
105+
u64_to_usize(block_end.saturating_sub(cursor)),
105106
)
106107
};
107108
if num_transferred_bytes < 0 {

src/snapshot-editor/src/edit_memory.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::path::PathBuf;
88

99
use clap::Subcommand;
1010
use fc_utils::seek_hole::SeekHole;
11+
use fc_utils::u64_to_usize;
1112

1213
#[derive(Debug, thiserror::Error, displaydoc::Display)]
1314
pub enum EditMemoryError {
@@ -89,7 +90,7 @@ fn rebase(memory_path: PathBuf, diff_path: PathBuf) -> Result<(), EditMemoryErro
8990
base_file.as_raw_fd(),
9091
diff_file.as_raw_fd(),
9192
(&mut cursor as *mut u64).cast::<i64>(),
92-
block_end.saturating_sub(cursor) as usize,
93+
u64_to_usize(block_end.saturating_sub(cursor)),
9394
)
9495
};
9596
if num_transferred_bytes < 0 {

src/snapshot-editor/src/utils.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::fs::{File, OpenOptions};
55
use std::path::PathBuf;
66

7+
use fc_utils::u64_to_usize;
78
use snapshot::Snapshot;
89
use vmm::persist::MicrovmState;
910
use vmm::version_map::VERSION_MAP;
@@ -29,7 +30,7 @@ pub fn open_vmstate(snapshot_path: &PathBuf) -> Result<(MicrovmState, u16), Util
2930
let version_map = VERSION_MAP.clone();
3031
let mut snapshot_reader = File::open(snapshot_path).map_err(UtilsError::VmStateFileOpen)?;
3132
let metadata = std::fs::metadata(snapshot_path).map_err(UtilsError::VmStateFileMeta)?;
32-
let snapshot_len = metadata.len() as usize;
33+
let snapshot_len = u64_to_usize(metadata.len());
3334
Snapshot::load(&mut snapshot_reader, snapshot_len, version_map).map_err(UtilsError::VmStateLoad)
3435
}
3536

src/utils/src/lib.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,12 @@ pub fn get_page_size() -> Result<usize, errno::Error> {
3131
ps => Ok(usize::try_from(ps).unwrap()),
3232
}
3333
}
34+
35+
/// Safely converts a u64 value to a usize value.
36+
/// This bypasses the Clippy lint check because we only support 64-bit platforms.
37+
#[cfg(target_pointer_width = "64")]
38+
#[inline]
39+
#[allow(clippy::cast_possible_truncation)]
40+
pub const fn u64_to_usize(num: u64) -> usize {
41+
num as usize
42+
}

src/utils/src/vm_memory.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ pub use vm_memory::{
1818
VolatileMemory, VolatileMemoryError, VolatileSlice,
1919
};
2020

21+
use crate::u64_to_usize;
22+
2123
pub type GuestMemoryMmap = vm_memory::GuestMemoryMmap<Option<AtomicBitmap>>;
2224
pub type GuestRegionMmap = vm_memory::GuestRegionMmap<Option<AtomicBitmap>>;
2325
pub type GuestMmapRegion = vm_memory::MmapRegion<Option<AtomicBitmap>>;
@@ -136,7 +138,7 @@ pub fn create_guest_memory(
136138
pub fn mark_dirty_mem(mem: &GuestMemoryMmap, addr: GuestAddress, len: usize) {
137139
let _ = mem.try_access(len, addr, |_total, count, caddr, region| {
138140
if let Some(bitmap) = region.bitmap() {
139-
bitmap.mark_dirty(caddr.0 as usize, count);
141+
bitmap.mark_dirty(u64_to_usize(caddr.0), count);
140142
}
141143
Ok(count)
142144
});
@@ -692,7 +694,7 @@ mod tests {
692694
*len,
693695
GuestAddress(*addr as u64),
694696
|_total, count, caddr, region| {
695-
let offset = caddr.0 as usize;
697+
let offset = usize::try_from(caddr.0).unwrap();
696698
let bitmap = region.bitmap().as_ref().unwrap();
697699
for i in offset..offset + count {
698700
assert_eq!(bitmap.dirty_at(i), *dirty);

src/vmm/src/arch/x86_64/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ pub mod regs;
2121
use linux_loader::configurator::linux::LinuxBootConfigurator;
2222
use linux_loader::configurator::{BootConfigurator, BootParams};
2323
use linux_loader::loader::bootparam::boot_params;
24+
use utils::u64_to_usize;
2425
use utils::vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion};
2526

2627
use crate::arch::InitrdConfig;
@@ -89,8 +90,7 @@ pub fn initrd_load_addr(
8990
let first_region = guest_mem
9091
.find_region(GuestAddress::new(0))
9192
.ok_or(ConfigurationError::InitrdAddress)?;
92-
// It's safe to cast to usize because the size of a region can't be greater than usize.
93-
let lowmem_size = first_region.len() as usize;
93+
let lowmem_size = u64_to_usize(first_region.len());
9494

9595
if lowmem_size < initrd_size {
9696
return Err(ConfigurationError::InitrdAddress);

src/vmm/src/builder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use snapshot::Persist;
2222
use userfaultfd::Uffd;
2323
use utils::eventfd::EventFd;
2424
use utils::time::TimestampUs;
25+
use utils::u64_to_usize;
2526
use utils::vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap, ReadVolatile};
2627
#[cfg(target_arch = "aarch64")]
2728
use vm_superio::Rtc;
@@ -491,7 +492,7 @@ pub fn build_microvm_from_snapshot(
491492

492493
vm_resources.update_vm_config(&MachineConfigUpdate {
493494
vcpu_count: Some(vcpu_count),
494-
mem_size_mib: Some(microvm_state.vm_info.mem_size_mib as usize),
495+
mem_size_mib: Some(u64_to_usize(microvm_state.vm_info.mem_size_mib)),
495496
smt: Some(microvm_state.vm_info.smt),
496497
cpu_template: Some(microvm_state.vm_info.cpu_template),
497498
track_dirty_pages: Some(track_dirty_pages),
@@ -626,7 +627,7 @@ where
626627
"Initrd image seek returned a size of zero",
627628
)))
628629
}
629-
Ok(s) => size = s as usize,
630+
Ok(s) => size = u64_to_usize(s),
630631
};
631632
// Go back to the image start
632633
image.seek(SeekFrom::Start(0)).map_err(InitrdRead)?;

src/vmm/src/devices/virtio/balloon/device.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use log::error;
1111
use serde::Serialize;
1212
use timerfd::{ClockId, SetTimeFlags, TimerFd, TimerState};
1313
use utils::eventfd::EventFd;
14+
use utils::u64_to_usize;
1415
use utils::vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemoryMmap};
1516
use virtio_gen::virtio_blk::VIRTIO_F_VERSION_1;
1617

@@ -600,7 +601,7 @@ impl VirtioDevice for Balloon {
600601
if let Some(end) = offset.checked_add(data.len() as u64) {
601602
// This write can't fail, offset and end are checked against config_len.
602603
data.write_all(
603-
&config_space_bytes[offset as usize..cmp::min(end, config_len) as usize],
604+
&config_space_bytes[u64_to_usize(offset)..u64_to_usize(cmp::min(end, config_len))],
604605
)
605606
.unwrap();
606607
}

src/vmm/src/devices/virtio/balloon/util.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
use std::io;
55

6+
use utils::u64_to_usize;
67
use utils::vm_memory::{GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion};
78

89
use super::{RemoveRegionError, MAX_PAGE_COMPACT_BUFFER};
@@ -88,7 +89,7 @@ pub(crate) fn remove_range(
8889
let ret = unsafe {
8990
libc::mmap(
9091
phys_address.cast(),
91-
range_len as usize,
92+
u64_to_usize(range_len),
9293
libc::PROT_READ | libc::PROT_WRITE,
9394
libc::MAP_FIXED | libc::MAP_ANONYMOUS | libc::MAP_PRIVATE,
9495
-1,
@@ -103,7 +104,7 @@ pub(crate) fn remove_range(
103104
// Madvise the region in order to mark it as not used.
104105
// SAFETY: The address and length are known to be valid.
105106
let ret = unsafe {
106-
let range_len = range_len as usize;
107+
let range_len = u64_to_usize(range_len);
107108
libc::madvise(phys_address.cast(), range_len, libc::MADV_DONTNEED)
108109
};
109110
if ret < 0 {

src/vmm/src/devices/virtio/block/device.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use block_io::FileEngine;
1818
use serde::{Deserialize, Serialize};
1919
use utils::eventfd::EventFd;
2020
use utils::kernel_version::{min_kernel_version_for_io_uring, KernelVersion};
21+
use utils::u64_to_usize;
2122
use utils::vm_memory::GuestMemoryMmap;
2223
use virtio_gen::virtio_blk::{
2324
VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_RO, VIRTIO_BLK_ID_BYTES, VIRTIO_F_VERSION_1,
@@ -583,8 +584,10 @@ impl VirtioDevice for Block {
583584
}
584585
if let Some(end) = offset.checked_add(data.len() as u64) {
585586
// This write can't fail, offset and end are checked against config_len.
586-
data.write_all(&self.config_space[offset as usize..cmp::min(end, config_len) as usize])
587-
.unwrap();
587+
data.write_all(
588+
&self.config_space[u64_to_usize(offset)..u64_to_usize(cmp::min(end, config_len))],
589+
)
590+
.unwrap();
588591
}
589592
}
590593

0 commit comments

Comments
 (0)