From ae7113e1d43c669a12f0e566f5e8d220a64ae741 Mon Sep 17 00:00:00 2001 From: Julian Schindel Date: Wed, 29 Apr 2026 21:55:06 +0200 Subject: [PATCH] virtio-devices: replace `as ` casts with safer alternatives `as` casts can change mutability, which quickly leads to undefined behavior. Signed-off-by: Julian Schindel --- virtio-devices/src/balloon.rs | 2 +- virtio-devices/src/block.rs | 9 +++------ virtio-devices/src/iommu.rs | 2 +- virtio-devices/src/mem.rs | 2 +- virtio-devices/src/vhost_user/blk.rs | 2 +- virtio-devices/src/vhost_user/vu_common_ctrl.rs | 2 +- virtio-devices/src/vsock/packet.rs | 2 +- 7 files changed, 9 insertions(+), 12 deletions(-) diff --git a/virtio-devices/src/balloon.rs b/virtio-devices/src/balloon.rs index 74b83dff2..5f9119fdf 100644 --- a/virtio-devices/src/balloon.rs +++ b/virtio-devices/src/balloon.rs @@ -185,7 +185,7 @@ impl BalloonEpollHandler { let res = // SAFETY: FFI call with valid arguments, guaranteed by VolatileSlice unsafe { - libc::madvise(slice.ptr_guard_mut().as_ptr() as *mut libc::c_void, + libc::madvise(slice.ptr_guard_mut().as_ptr().cast(), range_len as libc::size_t, advice) }; if res != 0 { return Err(Error::MadviseFail(io::Error::last_os_error())); diff --git a/virtio-devices/src/block.rs b/virtio-devices/src/block.rs index d37db6cd8..60ffade93 100644 --- a/virtio-devices/src/block.rs +++ b/virtio-devices/src/block.rs @@ -605,13 +605,10 @@ Setting device status to 'NEEDS_RESET' and stopping processing queues until rese // Schedule the thread to run on the expected CPU set if let Some(cpuset) = cpuset.as_ref() { + let cpuset: *const libc::cpu_set_t = cpuset; // SAFETY: FFI call with correct arguments let ret = unsafe { - libc::sched_setaffinity( - 0, - std::mem::size_of::(), - cpuset as *const libc::cpu_set_t, - ) + libc::sched_setaffinity(0, std::mem::size_of::(), cpuset) }; if ret != 0 { @@ -1070,7 +1067,7 @@ impl VirtioDevice for Block { fn write_config(&mut self, offset: u64, data: &[u8]) { // The "writeback" field is the only mutable field let writeback_offset = - (&self.config.writeback as *const _ as u64) - (&self.config as *const _ as u64); + (&raw const self.config.writeback as u64) - (&raw const self.config as u64); if offset != writeback_offset || data.len() != std::mem::size_of_val(&self.config.writeback) { error!( diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index c99de399a..baa2a2421 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -1081,7 +1081,7 @@ impl VirtioDevice for Iommu { fn write_config(&mut self, offset: u64, data: &[u8]) { // The "bypass" field is the only mutable field let bypass_offset = - (&self.config.bypass as *const _ as u64) - (&self.config as *const _ as u64); + (&raw const self.config.bypass as u64) - (&raw const self.config as u64); if offset != bypass_offset || data.len() != std::mem::size_of_val(&self.config.bypass) { error!( "Attempt to write to read-only field: offset {:x} length {}", diff --git a/virtio-devices/src/mem.rs b/virtio-devices/src/mem.rs index afc168a6e..e03252d1b 100644 --- a/virtio-devices/src/mem.rs +++ b/virtio-devices/src/mem.rs @@ -480,7 +480,7 @@ impl MemEpollHandler { // alone is not past the end. let res = unsafe { libc::madvise( - self.region.as_ptr().offset(offset as isize) as *mut libc::c_void, + self.region.as_ptr().offset(offset as isize).cast(), size as libc::size_t, libc::MADV_DONTNEED, ) diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index 5b64bbb5a..cddffc5d6 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -233,7 +233,7 @@ impl VirtioDevice for Blk { fn write_config(&mut self, offset: u64, data: &[u8]) { // The "writeback" field is the only mutable field let writeback_offset = - (&self.config.writeback as *const _ as u64) - (&self.config as *const _ as u64); + (&raw const self.config.writeback as u64) - (&raw const self.config as u64); if offset != writeback_offset || data.len() != std::mem::size_of_val(&self.config.writeback) { error!( diff --git a/virtio-devices/src/vhost_user/vu_common_ctrl.rs b/virtio-devices/src/vhost_user/vu_common_ctrl.rs index 5ad9425c5..ca19ffea2 100644 --- a/virtio-devices/src/vhost_user/vu_common_ctrl.rs +++ b/virtio-devices/src/vhost_user/vu_common_ctrl.rs @@ -687,7 +687,7 @@ impl VhostUserHandle { // SAFETY: region is of size len let bitmap: &[u64] = unsafe { // Cast the pointer to u64 - let ptr = region.as_ptr() as *const u64; + let ptr = region.as_ptr().cast(); std::slice::from_raw_parts(ptr, len) }; Ok(MemoryRangeTable::from_dirty_bitmap( diff --git a/virtio-devices/src/vsock/packet.rs b/virtio-devices/src/vsock/packet.rs index e9834b5f3..656b38805 100644 --- a/virtio-devices/src/vsock/packet.rs +++ b/virtio-devices/src/vsock/packet.rs @@ -396,7 +396,7 @@ impl VsockPacket { PacketBuffer::Borrowed { ptr, len } => { // SAFETY: bound checks have already been performed when creating the packet // from the virtq descriptor. - Some(unsafe { std::slice::from_raw_parts(*ptr as *const u8, *len) }) + Some(unsafe { std::slice::from_raw_parts((*ptr).cast(), *len) }) } } }