diff --git a/src/backend/libc/net/addr.rs b/src/backend/libc/net/addr.rs index 1699ffa99..483be735e 100644 --- a/src/backend/libc/net/addr.rs +++ b/src/backend/libc/net/addr.rs @@ -386,5 +386,5 @@ pub(crate) fn offsetof_sun_path() -> usize { #[cfg(target_os = "aix")] sun_path: [0; 1023], }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) + (crate::utils::as_ptr(&z.sun_path).addr()) - (crate::utils::as_ptr(&z).addr()) } diff --git a/src/backend/libc/param/auxv.rs b/src/backend/libc/param/auxv.rs index 6b6ea9555..8121ae05f 100644 --- a/src/backend/libc/param/auxv.rs +++ b/src/backend/libc/param/auxv.rs @@ -31,8 +31,8 @@ pub(crate) fn clock_ticks_per_second() -> u64 { pub(crate) fn linux_hwcap() -> (usize, usize) { if let Some(libc_getauxval) = getauxval.get() { unsafe { - let hwcap = libc_getauxval(c::AT_HWCAP) as usize; - let hwcap2 = libc_getauxval(c::AT_HWCAP2) as usize; + let hwcap = libc_getauxval(c::AT_HWCAP).addr(); + let hwcap2 = libc_getauxval(c::AT_HWCAP2).addr(); (hwcap, hwcap2) } } else { @@ -47,7 +47,7 @@ pub(crate) fn linux_hwcap() -> (usize, usize) { #[inline] pub(crate) fn linux_minsigstksz() -> usize { if let Some(libc_getauxval) = getauxval.get() { - unsafe { libc_getauxval(c::AT_MINSIGSTKSZ) as usize } + unsafe { libc_getauxval(c::AT_MINSIGSTKSZ).addr() } } else { 0 } diff --git a/src/backend/libc/thread/syscalls.rs b/src/backend/libc/thread/syscalls.rs index 9198a7fbe..79f8da699 100644 --- a/src/backend/libc/thread/syscalls.rs +++ b/src/backend/libc/thread/syscalls.rs @@ -30,6 +30,7 @@ use crate::timespec::{as_libc_timespec_mut_ptr, as_libc_timespec_ptr}; #[cfg(linux_kernel)] use crate::utils::option_as_ptr; use core::mem::MaybeUninit; +use core::ptr; #[cfg(linux_kernel)] use core::sync::atomic::AtomicU32; #[cfg(linux_kernel)] @@ -462,7 +463,7 @@ pub(crate) unsafe fn futex_val2( // the pointer. // // [“the kernel casts the timeout value first to unsigned long, then to uint32_t”]: https://man7.org/linux/man-pages/man2/futex.2.html - let timeout = val2 as usize as *const Timespec; + let timeout = ptr::without_provenance::(val2 as usize); #[cfg(all( target_pointer_width = "32", diff --git a/src/backend/linux_raw/conv.rs b/src/backend/linux_raw/conv.rs index 901451ae6..6fd6f4f9b 100644 --- a/src/backend/linux_raw/conv.rs +++ b/src/backend/linux_raw/conv.rs @@ -43,7 +43,7 @@ use crate::process::Resource; use crate::signal::Signal; use crate::utils::{as_mut_ptr, as_ptr}; use core::mem::MaybeUninit; -use core::ptr::null_mut; +use core::ptr::{self, null_mut}; #[cfg(any(feature = "thread", feature = "time"))] use linux_raw_sys::general::__kernel_clockid_t; #[cfg(target_pointer_width = "64")] @@ -102,7 +102,7 @@ pub(super) fn size_of<'a, T: Sized, Num: ArgNumber>() -> ArgReg<'a, Num> { /// pointer instead of casting to `usize`, so that provenance is preserved. #[inline] pub(super) fn pass_usize<'a, Num: ArgNumber>(t: usize) -> ArgReg<'a, Num> { - raw_arg(t as *mut _) + raw_arg(ptr::without_provenance_mut(t)) } impl<'a, Num: ArgNumber, T> From<*mut T> for ArgReg<'a, Num> { diff --git a/src/backend/linux_raw/fs/dir.rs b/src/backend/linux_raw/fs/dir.rs index 31ebc5437..f7cc04775 100644 --- a/src/backend/linux_raw/fs/dir.rs +++ b/src/backend/linux_raw/fs/dir.rs @@ -138,12 +138,12 @@ impl Dir { d_reclen: 0_u16, d_name: Default::default(), }; - let base = as_ptr(&z) as usize; - let offsetof_d_reclen = (as_ptr(&z.d_reclen) as usize) - base; - let offsetof_d_name = (as_ptr(&z.d_name) as usize) - base; - let offsetof_d_ino = (as_ptr(&z.d_ino) as usize) - base; - let offsetof_d_off = (as_ptr(&z.d_off) as usize) - base; - let offsetof_d_type = (as_ptr(&z.d_type) as usize) - base; + let base = as_ptr(&z).addr(); + let offsetof_d_reclen = as_ptr(&z.d_reclen).addr() - base; + let offsetof_d_name = as_ptr(&z.d_name).addr() - base; + let offsetof_d_ino = as_ptr(&z.d_ino).addr() - base; + let offsetof_d_off = as_ptr(&z.d_off).addr() - base; + let offsetof_d_type = as_ptr(&z.d_type).addr() - base; // Test if we need more entries, and if so, read more. if self.buf.len() - self.pos < size_of::() { diff --git a/src/backend/linux_raw/net/addr.rs b/src/backend/linux_raw/net/addr.rs index 7138b5713..303324e8c 100644 --- a/src/backend/linux_raw/net/addr.rs +++ b/src/backend/linux_raw/net/addr.rs @@ -296,5 +296,5 @@ pub(crate) fn offsetof_sun_path() -> usize { sun_family: 0_u16, sun_path: [0; 108], }; - (crate::utils::as_ptr(&z.sun_path) as usize) - (crate::utils::as_ptr(&z) as usize) + (crate::utils::as_ptr(&z.sun_path).addr()) - (crate::utils::as_ptr(&z).addr()) } diff --git a/src/backend/linux_raw/param/auxv.rs b/src/backend/linux_raw/param/auxv.rs index d748219a9..ce5599b6e 100644 --- a/src/backend/linux_raw/param/auxv.rs +++ b/src/backend/linux_raw/param/auxv.rs @@ -395,11 +395,11 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti for Elf_auxv_t { a_type, a_val } in aux_iter { match a_type as _ { - AT_PAGESZ => pagesz = a_val as usize, - AT_CLKTCK => clktck = a_val as usize, - AT_HWCAP => hwcap = a_val as usize, - AT_HWCAP2 => hwcap2 = a_val as usize, - AT_MINSIGSTKSZ => minsigstksz = a_val as usize, + AT_PAGESZ => pagesz = a_val.addr(), + AT_CLKTCK => clktck = a_val.addr(), + AT_HWCAP => hwcap = a_val.addr(), + AT_HWCAP2 => hwcap2 = a_val.addr(), + AT_MINSIGSTKSZ => minsigstksz = a_val.addr(), AT_EXECFN => execfn = check_raw_pointer::(a_val as *mut _)?.as_ptr(), AT_SYSINFO_EHDR => sysinfo_ehdr = check_elf_base(a_val as *mut _)?.as_ptr(), @@ -412,7 +412,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti } #[cfg(feature = "runtime")] - AT_SECURE => secure = (a_val as usize != 0) as u8 + 1, + AT_SECURE => secure = (a_val.addr() != 0) as u8 + 1, #[cfg(feature = "runtime")] AT_UID => uid = Some(a_val), #[cfg(feature = "runtime")] @@ -424,11 +424,11 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator) -> Opti #[cfg(feature = "runtime")] AT_PHDR => phdr = check_raw_pointer::(a_val as *mut _)?.as_ptr(), #[cfg(feature = "runtime")] - AT_PHNUM => phnum = a_val as usize, + AT_PHNUM => phnum = a_val.addr(), #[cfg(feature = "runtime")] - AT_PHENT => phent = a_val as usize, + AT_PHENT => phent = a_val.addr(), #[cfg(feature = "runtime")] - AT_ENTRY => entry = a_val as usize, + AT_ENTRY => entry = a_val.addr(), #[cfg(feature = "runtime")] AT_RANDOM => random = check_raw_pointer::<[u8; 16]>(a_val as *mut _)?.as_ptr(), diff --git a/src/backend/linux_raw/param/init.rs b/src/backend/linux_raw/param/init.rs index de1e59492..006ed339b 100644 --- a/src/backend/linux_raw/param/init.rs +++ b/src/backend/linux_raw/param/init.rs @@ -146,24 +146,24 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) { let Elf_auxv_t { a_type, a_val } = read(auxp); match a_type as _ { - AT_PAGESZ => PAGE_SIZE.store(a_val as usize, Ordering::Relaxed), - AT_CLKTCK => CLOCK_TICKS_PER_SECOND.store(a_val as usize, Ordering::Relaxed), - AT_HWCAP => HWCAP.store(a_val as usize, Ordering::Relaxed), - AT_HWCAP2 => HWCAP2.store(a_val as usize, Ordering::Relaxed), - AT_MINSIGSTKSZ => MINSIGSTKSZ.store(a_val as usize, Ordering::Relaxed), + AT_PAGESZ => PAGE_SIZE.store(a_val.addr(), Ordering::Relaxed), + AT_CLKTCK => CLOCK_TICKS_PER_SECOND.store(a_val.addr(), Ordering::Relaxed), + AT_HWCAP => HWCAP.store(a_val.addr(), Ordering::Relaxed), + AT_HWCAP2 => HWCAP2.store(a_val.addr(), Ordering::Relaxed), + AT_MINSIGSTKSZ => MINSIGSTKSZ.store(a_val.addr(), Ordering::Relaxed), AT_EXECFN => EXECFN.store(a_val.cast::(), Ordering::Relaxed), AT_SYSINFO_EHDR => SYSINFO_EHDR.store(a_val.cast::(), Ordering::Relaxed), #[cfg(feature = "runtime")] - AT_SECURE => SECURE.store(a_val as usize != 0, Ordering::Relaxed), + AT_SECURE => SECURE.store(a_val.addr() != 0, Ordering::Relaxed), #[cfg(feature = "runtime")] AT_PHDR => PHDR.store(a_val.cast::(), Ordering::Relaxed), #[cfg(feature = "runtime")] - AT_PHNUM => PHNUM.store(a_val as usize, Ordering::Relaxed), + AT_PHNUM => PHNUM.store(a_val.addr(), Ordering::Relaxed), #[cfg(feature = "runtime")] - AT_PHENT => PHENT.store(a_val as usize, Ordering::Relaxed), + AT_PHENT => PHENT.store(a_val.addr(), Ordering::Relaxed), #[cfg(feature = "runtime")] - AT_ENTRY => ENTRY.store(a_val as usize, Ordering::Relaxed), + AT_ENTRY => ENTRY.store(a_val.addr(), Ordering::Relaxed), #[cfg(feature = "runtime")] AT_RANDOM => RANDOM.store(a_val.cast::<[u8; 16]>(), Ordering::Relaxed), diff --git a/src/backend/linux_raw/param/libc_auxv.rs b/src/backend/linux_raw/param/libc_auxv.rs index d77d3a840..a201ea8c5 100644 --- a/src/backend/linux_raw/param/libc_auxv.rs +++ b/src/backend/linux_raw/param/libc_auxv.rs @@ -74,8 +74,8 @@ pub(crate) fn linux_hwcap() -> (usize, usize) { #[cfg(not(feature = "runtime"))] unsafe { if let Some(libc_getauxval) = getauxval.get() { - let hwcap = libc_getauxval(AT_HWCAP) as usize; - let hwcap2 = libc_getauxval(AT_HWCAP2) as usize; + let hwcap = libc_getauxval(AT_HWCAP).addr(); + let hwcap2 = libc_getauxval(AT_HWCAP2).addr(); (hwcap, hwcap2) } else { (0, 0) @@ -84,8 +84,8 @@ pub(crate) fn linux_hwcap() -> (usize, usize) { #[cfg(feature = "runtime")] unsafe { - let hwcap = getauxval(AT_HWCAP) as usize; - let hwcap2 = getauxval(AT_HWCAP2) as usize; + let hwcap = getauxval(AT_HWCAP).addr(); + let hwcap2 = getauxval(AT_HWCAP2).addr(); (hwcap, hwcap2) } } @@ -102,7 +102,7 @@ pub(crate) fn linux_minsigstksz() -> usize { #[cfg(feature = "runtime")] unsafe { - getauxval(AT_MINSIGSTKSZ) as usize + getauxval(AT_MINSIGSTKSZ).addr() } } @@ -127,7 +127,7 @@ pub(crate) fn linux_execfn() -> &'static CStr { #[cfg(feature = "runtime")] #[inline] pub(crate) fn linux_secure() -> bool { - unsafe { getauxval(AT_SECURE) as usize != 0 } + unsafe { getauxval(AT_SECURE).addr() != 0 } } #[cfg(feature = "runtime")] @@ -135,8 +135,8 @@ pub(crate) fn linux_secure() -> bool { pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) { unsafe { let phdr: *const c::c_void = getauxval(AT_PHDR); - let phent = getauxval(AT_PHENT) as usize; - let phnum = getauxval(AT_PHNUM) as usize; + let phent = getauxval(AT_PHENT).addr(); + let phnum = getauxval(AT_PHNUM).addr(); (phdr, phent, phnum) } } @@ -163,7 +163,7 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr { #[cfg(feature = "runtime")] #[inline] pub(crate) fn entry() -> usize { - unsafe { getauxval(AT_ENTRY) as usize } + unsafe { getauxval(AT_ENTRY).addr() } } #[cfg(feature = "runtime")] diff --git a/src/backend/linux_raw/reg.rs b/src/backend/linux_raw/reg.rs index 57a8d2697..fa37f5799 100644 --- a/src/backend/linux_raw/reg.rs +++ b/src/backend/linux_raw/reg.rs @@ -16,6 +16,7 @@ use super::c; use super::fd::RawFd; use core::marker::PhantomData; use core::ops::Range; +use core::ptr; pub(super) trait ToAsm: private::Sealed { /// Convert `self` to a `usize` ready to be passed to a syscall @@ -113,8 +114,8 @@ pub(super) struct RetReg { impl RetReg { #[inline] pub(super) fn decode_usize(self) -> usize { - debug_assert!(!(-4095..0).contains(&(self.raw as isize))); - self.raw as usize + debug_assert!(!(-4095..0).contains(&(self.raw.addr() as isize))); + self.raw.addr() } #[inline] @@ -169,7 +170,7 @@ impl RetReg { #[inline] pub(super) fn decode_error_code(self) -> u16 { - let bits = self.raw as usize; + let bits = self.raw.addr(); // `raw` must be in `-4095..0`. Linux always returns errors in // `-4095..0`, and we double-check it here. @@ -185,12 +186,12 @@ impl RetReg { #[inline] pub(super) fn is_negative(&self) -> bool { - (self.raw as isize) < 0 + (self.raw.addr() as isize) < 0 } #[inline] pub(super) fn is_in_range(&self, range: Range) -> bool { - range.contains(&(self.raw as isize)) + range.contains(&(self.raw.addr() as isize)) } } @@ -213,7 +214,7 @@ pub(super) struct SyscallNumber<'a> { impl<'a> ToAsm for SyscallNumber<'a> { #[inline] unsafe fn to_asm(self) -> *mut Opaque { - self.nr as usize as *mut Opaque + ptr::without_provenance_mut(self.nr as usize) } } diff --git a/src/backend/linux_raw/thread/syscalls.rs b/src/backend/linux_raw/thread/syscalls.rs index 352e06150..576cdcc3d 100644 --- a/src/backend/linux_raw/thread/syscalls.rs +++ b/src/backend/linux_raw/thread/syscalls.rs @@ -19,6 +19,7 @@ use crate::thread::{ }; use crate::utils::as_mut_ptr; use core::mem::MaybeUninit; +use core::ptr; use core::sync::atomic::AtomicU32; #[cfg(target_pointer_width = "32")] use linux_raw_sys::general::timespec as __kernel_old_timespec; @@ -219,7 +220,7 @@ pub(crate) unsafe fn futex_val2( // the pointer. // // [“the kernel casts the timeout value first to unsigned long, then to uint32_t”]: https://man7.org/linux/man-pages/man2/futex.2.html - let timeout = val2 as usize as *const Timespec; + let timeout = ptr::without_provenance::(val2 as usize); #[cfg(target_pointer_width = "32")] { diff --git a/src/backend/linux_raw/vdso.rs b/src/backend/linux_raw/vdso.rs index 4fa1d1ccf..a541b5148 100644 --- a/src/backend/linux_raw/vdso.rs +++ b/src/backend/linux_raw/vdso.rs @@ -373,8 +373,8 @@ impl Vdso { { let sum = self.addr_from_elf(sym.st_value).unwrap(); assert!( - sum as usize >= self.load_addr as usize - && sum as usize <= self.load_end as usize + sum.addr() >= self.load_addr.addr() + && sum.addr() <= self.load_end.addr() ); return sum as *mut c::c_void; } @@ -393,8 +393,8 @@ impl Vdso { { let sum = self.addr_from_elf(sym.st_value).unwrap(); assert!( - sum as usize >= self.load_addr as usize - && sum as usize <= self.load_end as usize + sum.addr() >= self.load_addr.addr() + && sum.addr() <= self.load_end.addr() ); return sum as *mut c::c_void; } @@ -409,7 +409,7 @@ impl Vdso { /// Add the given address to the vDSO base address. unsafe fn base_plus(&self, offset: usize) -> Option<*const c_void> { // Check for overflow. - let _ = (self.load_addr as usize).checked_add(offset)?; + let _ = (self.load_addr.addr()).checked_add(offset)?; // Add the offset to the base. Some(self.load_addr.cast::().add(offset).cast()) } diff --git a/src/event/kqueue.rs b/src/event/kqueue.rs index 897d93980..7815f152f 100644 --- a/src/event/kqueue.rs +++ b/src/event/kqueue.rs @@ -80,7 +80,8 @@ impl Event { }, udata: { // On NetBSD, udata is an `isize` and not a pointer. - udata as _ + // TODO: Strict provenance, prevent int-to-ptr cast. + core::ptr::from_exposed_addr_mut(udata as usize) }, ..unsafe { zeroed() } }, @@ -95,7 +96,8 @@ impl Event { /// Get the user data for this event. pub fn udata(&self) -> *mut c::c_void { // On NetBSD, udata is an isize and not a pointer. - self.inner.udata as _ + // TODO: Strict provenance, prevent ptr-to-int cast. + self.inner.udata.expose_addr() as isize } /// Get the raw data for this event. diff --git a/src/fs/ioctl.rs b/src/fs/ioctl.rs index c126fdd19..bebe2b8bc 100644 --- a/src/fs/ioctl.rs +++ b/src/fs/ioctl.rs @@ -83,7 +83,7 @@ unsafe impl ioctl::Ioctl for Ficlone<'_> { } fn as_ptr(&mut self) -> *mut c::c_void { - self.0.as_raw_fd() as *mut c::c_void + core::ptr::without_provenance_mut(self.0.as_raw_fd() as usize) } unsafe fn output_from_ptr( diff --git a/src/io_uring/mod.rs b/src/io_uring/mod.rs index 5e3756812..f8be1c918 100644 --- a/src/io_uring/mod.rs +++ b/src/io_uring/mod.rs @@ -312,7 +312,7 @@ pub unsafe fn io_uring_enter_reg_wait( to_submit, min_complete, flags, - reg_wait as *mut c_void, + core::ptr::without_provenance_mut(reg_wait), size_of::(), ) } @@ -1997,8 +1997,8 @@ mod tests { // io_uring stores them in a `u64`. unsafe { const MAGIC: u64 = !0x0123_4567_89ab_cdef; - let ptr = io_uring_ptr::new(MAGIC as usize as *mut c_void); - assert_eq!(ptr.ptr, MAGIC as usize as *mut c_void); + let ptr = io_uring_ptr::new(core::ptr::without_provenance_mut(MAGIC as usize)); + assert_eq!(ptr.ptr, core::ptr::without_provenance_mut(MAGIC as usize)); #[cfg(target_pointer_width = "16")] assert_eq!(ptr.__pad16, 0); #[cfg(any(target_pointer_width = "16", target_pointer_width = "32"))] @@ -2021,8 +2021,12 @@ mod tests { core::mem::transmute::(user_data), MAGIC ); - let user_data = io_uring_user_data::from_ptr(MAGIC as usize as *mut c_void); - assert_eq!(user_data.ptr(), MAGIC as usize as *mut c_void); + let user_data = + io_uring_user_data::from_ptr(core::ptr::without_provenance_mut(MAGIC as usize)); + assert_eq!( + user_data.ptr(), + core::ptr::without_provenance_mut(MAGIC as usize) + ); assert_eq!( core::mem::transmute::(user_data), MAGIC as usize as u64 diff --git a/src/ioctl/patterns.rs b/src/ioctl/patterns.rs index a08aae74e..c09e5bf40 100644 --- a/src/ioctl/patterns.rs +++ b/src/ioctl/patterns.rs @@ -230,7 +230,9 @@ impl IntegerSetter { /// - The integer is in the valid range for this opcode. #[inline] pub const unsafe fn new_usize(value: usize) -> Self { - Self { value: value as _ } + Self { + value: core::ptr::without_provenance_mut(value), + } } /// Create a new integer `Ioctl` helper containing a `*mut c_void`. diff --git a/src/lib.rs b/src/lib.rs index 1621262ed..7e53798a1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -96,6 +96,10 @@ //! [`Arg`]: path::Arg //! [support for externally defined flags]: bitflags#externally-defined-flags +#![feature(strict_provenance)] +#![feature(strict_provenance_lints)] +#![deny(fuzzy_provenance_casts)] +#![deny(lossy_provenance_casts)] #![deny(missing_docs)] #![allow(stable_features)] #![cfg_attr(linux_raw, deny(unsafe_code))] diff --git a/src/net/send_recv/msg.rs b/src/net/send_recv/msg.rs index 7df60a5e7..7d4010c7f 100644 --- a/src/net/send_recv/msg.rs +++ b/src/net/send_recv/msg.rs @@ -478,7 +478,7 @@ fn align_for_cmsghdr(buffer: &mut [MaybeUninit]) -> &mut [MaybeUninit] { } let align = align_of::(); - let addr = buffer.as_ptr() as usize; + let addr = buffer.as_ptr().addr(); let adjusted = (addr + (align - 1)) & align.wrapping_neg(); &mut buffer[adjusted - addr..] } diff --git a/src/process/prctl.rs b/src/process/prctl.rs index 8b08409c1..a41d74072 100644 --- a/src/process/prctl.rs +++ b/src/process/prctl.rs @@ -7,7 +7,7 @@ use core::mem::size_of; use core::num::NonZeroI32; -use core::ptr::{null, null_mut, NonNull}; +use core::ptr::{self, null, null_mut, NonNull}; use bitflags::bitflags; @@ -65,7 +65,7 @@ const PR_SET_PDEATHSIG: c_int = 1; #[doc(alias = "PR_SET_PDEATHSIG")] pub fn set_parent_process_death_signal(signal: Option) -> io::Result<()> { let signal = signal.map_or(0_usize, |signal| signal.as_raw() as usize); - unsafe { prctl_2args(PR_SET_PDEATHSIG, signal as *mut _) }.map(|_r| ()) + unsafe { prctl_2args(PR_SET_PDEATHSIG, ptr::without_provenance_mut(signal)) }.map(|_r| ()) } // @@ -138,7 +138,13 @@ const PR_SET_DUMPABLE: c_int = 4; #[inline] #[doc(alias = "PR_SET_DUMPABLE")] pub fn set_dumpable_behavior(config: DumpableBehavior) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_DUMPABLE, config as usize as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_DUMPABLE, + ptr::without_provenance_mut(config as usize), + ) + } + .map(|_r| ()) } // @@ -190,7 +196,13 @@ const PR_SET_UNALIGN: c_int = 6; #[inline] #[doc(alias = "PR_SET_UNALIGN")] pub fn set_unaligned_access_control(config: UnalignedAccessControl) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_UNALIGN, config.bits() as usize as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_UNALIGN, + ptr::without_provenance_mut(config.bits() as usize), + ) + } + .map(|_r| ()) } // @@ -241,7 +253,13 @@ const PR_SET_FPEMU: c_int = 10; pub fn set_floating_point_emulation_control( config: FloatingPointEmulationControl, ) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_FPEMU, config.bits() as usize as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_FPEMU, + ptr::without_provenance_mut(config.bits() as usize), + ) + } + .map(|_r| ()) } // @@ -304,7 +322,7 @@ pub fn set_floating_point_exception_mode( config: Option, ) -> io::Result<()> { let config = config.as_ref().map_or(0, FloatingPointExceptionMode::bits); - unsafe { prctl_2args(PR_SET_FPEXC, config as usize as *mut _) }.map(|_r| ()) + unsafe { prctl_2args(PR_SET_FPEXC, ptr::without_provenance_mut(config as usize)) }.map(|_r| ()) } // @@ -363,7 +381,7 @@ const PR_SET_TIMING: c_int = 14; #[inline] #[doc(alias = "PR_SET_TIMING")] pub fn set_timing_method(method: TimingMethod) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_TIMING, method as usize as *mut _) }.map(|_r| ()) + unsafe { prctl_2args(PR_SET_TIMING, ptr::without_provenance_mut(method as usize)) }.map(|_r| ()) } // @@ -429,7 +447,7 @@ const PR_SET_ENDIAN: c_int = 20; #[inline] #[doc(alias = "PR_SET_ENDIAN")] pub unsafe fn set_endian_mode(mode: EndianMode) -> io::Result<()> { - prctl_2args(PR_SET_ENDIAN, mode as usize as *mut _).map(|_r| ()) + prctl_2args(PR_SET_ENDIAN, ptr::without_provenance_mut(mode as usize)).map(|_r| ()) } // @@ -490,7 +508,13 @@ const PR_SET_TSC: c_int = 26; pub fn set_time_stamp_counter_readability( readability: TimeStampCounterReadability, ) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_TSC, readability as usize as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_TSC, + ptr::without_provenance_mut(readability as usize), + ) + } + .map(|_r| ()) } // @@ -592,12 +616,22 @@ pub fn set_machine_check_memory_corruption_kill_policy( policy: Option, ) -> io::Result<()> { let (sub_operation, policy) = if let Some(policy) = policy { - (PR_MCE_KILL_SET, policy as usize as *mut _) + ( + PR_MCE_KILL_SET, + ptr::without_provenance_mut(policy as usize), + ) } else { (PR_MCE_KILL_CLEAR, null_mut()) }; - unsafe { prctl_3args(PR_MCE_KILL, sub_operation as *mut _, policy) }.map(|_r| ()) + unsafe { + prctl_3args( + PR_MCE_KILL, + ptr::without_provenance_mut(sub_operation), + policy, + ) + } + .map(|_r| ()) } // @@ -672,7 +706,12 @@ pub unsafe fn set_virtual_memory_map_address( address: Option>, ) -> io::Result<()> { let address = address.map_or_else(null_mut, NonNull::as_ptr); - prctl_3args(PR_SET_MM, option as usize as *mut _, address).map(|_r| ()) + prctl_3args( + PR_SET_MM, + ptr::without_provenance_mut(option as usize), + address, + ) + .map(|_r| ()) } /// Supersede the `/proc/pid/exe` symbolic link with a new one pointing to a @@ -687,7 +726,14 @@ pub unsafe fn set_virtual_memory_map_address( #[doc(alias = "PR_SET_MM_EXE_FILE")] pub fn set_executable_file(fd: BorrowedFd<'_>) -> io::Result<()> { let fd = usize::try_from(fd.as_raw_fd()).map_err(|_r| io::Errno::RANGE)?; - unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_EXE_FILE as *mut _, fd as *mut _) }.map(|_r| ()) + unsafe { + prctl_3args( + PR_SET_MM, + ptr::without_provenance_mut(PR_SET_MM_EXE_FILE), + ptr::without_provenance_mut(fd), + ) + } + .map(|_r| ()) } /// Set a new auxiliary vector. @@ -707,9 +753,9 @@ pub fn set_executable_file(fd: BorrowedFd<'_>) -> io::Result<()> { pub unsafe fn set_auxiliary_vector(auxv: &[*const c_void]) -> io::Result<()> { syscalls::prctl( PR_SET_MM, - PR_SET_MM_AUXV as *mut _, + ptr::without_provenance_mut(PR_SET_MM_AUXV), auxv.as_ptr() as *mut _, - auxv.len() as *mut _, + ptr::without_provenance_mut(auxv.len()), null_mut(), ) .map(|_r| ()) @@ -727,7 +773,13 @@ pub unsafe fn set_auxiliary_vector(auxv: &[*const c_void]) -> io::Result<()> { pub fn virtual_memory_map_config_struct_size() -> io::Result { let mut value: c_uint = 0; let value_ptr = as_mut_ptr(&mut value); - unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_MAP_SIZE as *mut _, value_ptr.cast())? }; + unsafe { + prctl_3args( + PR_SET_MM, + ptr::without_provenance_mut(PR_SET_MM_MAP_SIZE), + value_ptr.cast(), + )? + }; Ok(value as usize) } @@ -786,9 +838,9 @@ pub struct PrctlMmMap { pub unsafe fn configure_virtual_memory_map(config: &PrctlMmMap) -> io::Result<()> { syscalls::prctl( PR_SET_MM, - PR_SET_MM_MAP as *mut _, + ptr::without_provenance_mut(PR_SET_MM_MAP), as_ptr(config) as *mut _, - size_of::() as *mut _, + ptr::without_provenance_mut(size_of::()), null_mut(), ) .map(|_r| ()) @@ -825,8 +877,8 @@ pub enum PTracer { pub fn set_ptracer(tracer: PTracer) -> io::Result<()> { let pid = match tracer { PTracer::None => null_mut(), - PTracer::Any => PR_SET_PTRACER_ANY as *mut _, - PTracer::ProcessID(pid) => pid.as_raw_nonzero().get() as usize as *mut _, + PTracer::Any => ptr::without_provenance_mut(PR_SET_PTRACER_ANY), + PTracer::ProcessID(pid) => ptr::without_provenance_mut(pid.as_raw_nonzero().get() as usize), }; unsafe { prctl_2args(PR_SET_PTRACER, pid) }.map(|_r| ()) @@ -865,7 +917,7 @@ const PR_SET_CHILD_SUBREAPER: c_int = 36; #[doc(alias = "PR_SET_CHILD_SUBREAPER")] pub fn set_child_subreaper(pid: Option) -> io::Result<()> { let pid = pid.map_or(0_usize, |pid| pid.as_raw_nonzero().get() as usize); - unsafe { prctl_2args(PR_SET_CHILD_SUBREAPER, pid as *mut _) }.map(|_r| ()) + unsafe { prctl_2args(PR_SET_CHILD_SUBREAPER, ptr::without_provenance_mut(pid)) }.map(|_r| ()) } // @@ -924,7 +976,7 @@ const PR_SET_FP_MODE: c_int = 45; #[inline] #[doc(alias = "PR_SET_FP_MODE")] pub fn set_floating_point_mode(mode: FloatingPointMode) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_FP_MODE, mode as usize as *mut _) }.map(|_r| ()) + unsafe { prctl_2args(PR_SET_FP_MODE, ptr::without_provenance_mut(mode as usize)) }.map(|_r| ()) } // @@ -1013,7 +1065,12 @@ bitflags! { pub fn speculative_feature_state( feature: SpeculationFeature, ) -> io::Result> { - let r = unsafe { prctl_2args(PR_GET_SPECULATION_CTRL, feature as usize as *mut _)? } as c_uint; + let r = unsafe { + prctl_2args( + PR_GET_SPECULATION_CTRL, + ptr::without_provenance_mut(feature as usize), + )? + } as c_uint; Ok(SpeculationFeatureState::from_bits(r)) } @@ -1031,8 +1088,8 @@ pub fn control_speculative_feature( feature: SpeculationFeature, config: SpeculationFeatureControl, ) -> io::Result<()> { - let feature = feature as usize as *mut _; - let config = config.bits() as usize as *mut _; + let feature = ptr::without_provenance_mut(feature as usize); + let config = ptr::without_provenance_mut(config.bits() as usize); unsafe { prctl_3args(PR_SET_SPECULATION_CTRL, feature, config) }.map(|_r| ()) } @@ -1066,7 +1123,13 @@ const PR_SET_IO_FLUSHER: c_int = 57; #[inline] #[doc(alias = "PR_SET_IO_FLUSHER")] pub fn configure_io_flusher_behavior(enable: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_IO_FLUSHER, usize::from(enable) as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_IO_FLUSHER, + ptr::without_provenance_mut(usize::from(enable)), + ) + } + .map(|_r| ()) } // @@ -1128,8 +1191,8 @@ pub unsafe fn configure_pointer_authentication_keys< prctl_3args( PR_PAC_SET_ENABLED_KEYS, - affected_keys as usize as *mut _, - enabled_keys as usize as *mut _, + ptr::without_provenance_mut(affected_keys as usize), + ptr::without_provenance_mut(enabled_keys as usize), ) .map(|_r| ()) } @@ -1155,9 +1218,9 @@ pub fn set_virtual_memory_region_name(region: &[u8], name: Option<&CStr>) -> io: unsafe { syscalls::prctl( PR_SET_VMA, - PR_SET_VMA_ANON_NAME as *mut _, + ptr::without_provenance_mut(PR_SET_VMA_ANON_NAME), region.as_ptr() as *mut _, - region.len() as *mut _, + ptr::without_provenance_mut(region.len()), name.map_or_else(null, CStr::as_ptr) as *mut _, ) .map(|_r| ()) diff --git a/src/process/procctl.rs b/src/process/procctl.rs index 24d553027..fe0d8a73c 100644 --- a/src/process/procctl.rs +++ b/src/process/procctl.rs @@ -163,7 +163,13 @@ pub enum DumpableBehavior { /// [FreeBSD `procctl(PROC_TRACE_CTL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn set_dumpable_behavior(process: ProcSelector, config: DumpableBehavior) -> io::Result<()> { - unsafe { procctl(PROC_TRACE_CTL, process, config as usize as *mut _) } + unsafe { + procctl( + PROC_TRACE_CTL, + process, + ptr::from_exposed_addr_mut(config as usize), + ) + } } // diff --git a/src/pty.rs b/src/pty.rs index 560dfc136..2fbbcebdb 100644 --- a/src/pty.rs +++ b/src/pty.rs @@ -211,7 +211,7 @@ unsafe impl ioctl::Ioctl for Tiocgptpeer { } fn as_ptr(&mut self) -> *mut c::c_void { - self.0.bits() as *mut c::c_void + core::ptr::without_provenance_mut(self.0.bits() as usize) } unsafe fn output_from_ptr( diff --git a/src/thread/prctl.rs b/src/thread/prctl.rs index 4719b1eb4..ed6e624a2 100644 --- a/src/thread/prctl.rs +++ b/src/thread/prctl.rs @@ -54,7 +54,13 @@ const PR_SET_KEEPCAPS: c_int = 8; /// [`prctl(PR_SET_KEEPCAPS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn set_keep_capabilities(enable: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_KEEPCAPS, usize::from(enable) as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_KEEPCAPS, + ptr::without_provenance_mut(usize::from(enable)), + ) + } + .map(|_r| ()) } // @@ -168,7 +174,7 @@ const PR_SET_SECCOMP: c_int = 22; /// [`prctl(PR_SET_SECCOMP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn set_secure_computing_mode(mode: SecureComputingMode) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_SECCOMP, mode as usize as *mut _) }.map(|_r| ()) + unsafe { prctl_2args(PR_SET_SECCOMP, ptr::without_provenance_mut(mode as usize)) }.map(|_r| ()) } // @@ -392,7 +398,13 @@ pub enum Capability { /// [`prctl(PR_CAPBSET_READ,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn capability_is_in_bounding_set(capability: Capability) -> io::Result { - unsafe { prctl_2args(PR_CAPBSET_READ, capability as usize as *mut _) }.map(|r| r != 0) + unsafe { + prctl_2args( + PR_CAPBSET_READ, + ptr::without_provenance_mut(capability as usize), + ) + } + .map(|r| r != 0) } const PR_CAPBSET_DROP: c_int = 24; @@ -407,7 +419,13 @@ const PR_CAPBSET_DROP: c_int = 24; /// [`prctl(PR_CAPBSET_DROP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn remove_capability_from_bounding_set(capability: Capability) -> io::Result<()> { - unsafe { prctl_2args(PR_CAPBSET_DROP, capability as usize as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_CAPBSET_DROP, + ptr::without_provenance_mut(capability as usize), + ) + } + .map(|_r| ()) } // @@ -481,7 +499,13 @@ const PR_SET_SECUREBITS: c_int = 28; /// [`prctl(PR_SET_SECUREBITS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn set_capabilities_secure_bits(bits: CapabilitiesSecureBits) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_SECUREBITS, bits.bits() as usize as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_SECUREBITS, + ptr::without_provenance_mut(bits.bits() as usize), + ) + } + .map(|_r| ()) } // @@ -512,7 +536,7 @@ const PR_SET_TIMERSLACK: c_int = 29; #[inline] pub fn set_current_timer_slack(value: Option) -> io::Result<()> { let value = usize::try_from(value.map_or(0, NonZeroU64::get)).map_err(|_r| io::Errno::RANGE)?; - unsafe { prctl_2args(PR_SET_TIMERSLACK, value as *mut _) }.map(|_r| ()) + unsafe { prctl_2args(PR_SET_TIMERSLACK, ptr::without_provenance_mut(value)) }.map(|_r| ()) } // @@ -542,7 +566,13 @@ const PR_SET_NO_NEW_PRIVS: c_int = 38; /// [`prctl(PR_SET_NO_NEW_PRIVS,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn set_no_new_privs(no_new_privs: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_NO_NEW_PRIVS, usize::from(no_new_privs) as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_NO_NEW_PRIVS, + ptr::without_provenance_mut(usize::from(no_new_privs)), + ) + } + .map(|_r| ()) } // @@ -590,7 +620,13 @@ const PR_SET_THP_DISABLE: c_int = 41; /// [`prctl(PR_SET_THP_DISABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn disable_transparent_huge_pages(thp_disable: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_THP_DISABLE, usize::from(thp_disable) as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_SET_THP_DISABLE, + ptr::without_provenance_mut(usize::from(thp_disable)), + ) + } + .map(|_r| ()) } // @@ -609,8 +645,15 @@ const PR_CAP_AMBIENT_IS_SET: usize = 1; /// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_IS_SET,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn capability_is_in_ambient_set(capability: Capability) -> io::Result { - let cap = capability as usize as *mut _; - unsafe { prctl_3args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_IS_SET as *mut _, cap) }.map(|r| r != 0) + let cap = ptr::without_provenance_mut(capability as usize); + unsafe { + prctl_3args( + PR_CAP_AMBIENT, + ptr::without_provenance_mut(PR_CAP_AMBIENT_IS_SET), + cap, + ) + } + .map(|r| r != 0) } const PR_CAP_AMBIENT_CLEAR_ALL: usize = 4; @@ -623,7 +666,13 @@ const PR_CAP_AMBIENT_CLEAR_ALL: usize = 4; /// [`prctl(PR_CAP_AMBIENT,PR_CAP_AMBIENT_CLEAR_ALL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub fn clear_ambient_capability_set() -> io::Result<()> { - unsafe { prctl_2args(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL as *mut _) }.map(|_r| ()) + unsafe { + prctl_2args( + PR_CAP_AMBIENT, + ptr::without_provenance_mut(PR_CAP_AMBIENT_CLEAR_ALL), + ) + } + .map(|_r| ()) } const PR_CAP_AMBIENT_RAISE: usize = 2; @@ -642,9 +691,16 @@ pub fn configure_capability_in_ambient_set(capability: Capability, enable: bool) } else { PR_CAP_AMBIENT_LOWER }; - let cap = capability as usize as *mut _; + let cap = ptr::without_provenance_mut(capability as usize); - unsafe { prctl_3args(PR_CAP_AMBIENT, sub_operation as *mut _, cap) }.map(|_r| ()) + unsafe { + prctl_3args( + PR_CAP_AMBIENT, + ptr::without_provenance_mut(sub_operation), + cap, + ) + } + .map(|_r| ()) } // @@ -714,7 +770,7 @@ pub unsafe fn set_sve_vector_length_configuration( bits |= PR_SVE_SET_VL_ONEXEC; } - prctl_2args(PR_SVE_SET_VL, bits as usize as *mut _).map(|_r| ()) + prctl_2args(PR_SVE_SET_VL, ptr::without_provenance_mut(bits as usize)).map(|_r| ()) } // @@ -740,7 +796,11 @@ pub unsafe fn reset_pointer_authentication_keys( keys: Option, ) -> io::Result<()> { let keys = keys.as_ref().map_or(0_u32, PointerAuthenticationKeys::bits); - prctl_2args(PR_PAC_RESET_KEYS, keys as usize as *mut _).map(|_r| ()) + prctl_2args( + PR_PAC_RESET_KEYS, + ptr::without_provenance_mut(keys as usize), + ) + .map(|_r| ()) } // @@ -805,7 +865,11 @@ pub unsafe fn set_current_tagged_address_mode( ) -> io::Result<()> { let config = mode.as_ref().map_or(0_u32, TaggedAddressMode::bits) | ((mte_tag << PR_MTE_TAG_SHIFT) & PR_MTE_TAG_MASK); - prctl_2args(PR_SET_TAGGED_ADDR_CTRL, config as usize as *mut _).map(|_r| ()) + prctl_2args( + PR_SET_TAGGED_ADDR_CTRL, + ptr::without_provenance_mut(config as usize), + ) + .map(|_r| ()) } // @@ -829,7 +893,11 @@ const PR_SYS_DISPATCH_OFF: usize = 0; /// [`prctl(PR_SET_SYSCALL_USER_DISPATCH,PR_SYS_DISPATCH_OFF,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html #[inline] pub unsafe fn disable_syscall_user_dispatch() -> io::Result<()> { - prctl_2args(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_OFF as *mut _).map(|_r| ()) + prctl_2args( + PR_SET_SYSCALL_USER_DISPATCH, + ptr::without_provenance_mut(PR_SYS_DISPATCH_OFF), + ) + .map(|_r| ()) } const PR_SYS_DISPATCH_ON: usize = 1; @@ -880,9 +948,9 @@ pub unsafe fn enable_syscall_user_dispatch( ) -> io::Result<()> { syscalls::prctl( PR_SET_SYSCALL_USER_DISPATCH, - PR_SYS_DISPATCH_ON as *mut _, + ptr::without_provenance_mut(PR_SYS_DISPATCH_ON), always_allowed_region.as_ptr() as *mut _, - always_allowed_region.len() as *mut _, + ptr::without_provenance_mut(always_allowed_region.len()), as_ptr(fast_switch_flag) as *mut _, ) .map(|_r| ()) @@ -938,9 +1006,9 @@ pub fn core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io::Resul unsafe { syscalls::prctl( PR_SCHED_CORE, - PR_SCHED_CORE_GET as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, + ptr::without_provenance_mut(PR_SCHED_CORE_GET), + ptr::without_provenance_mut(pid.as_raw_nonzero().get() as usize), + ptr::without_provenance_mut(scope as usize), value.as_mut_ptr().cast(), )?; Ok(value.assume_init()) @@ -960,9 +1028,9 @@ pub fn create_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io unsafe { syscalls::prctl( PR_SCHED_CORE, - PR_SCHED_CORE_CREATE as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, + ptr::without_provenance_mut(PR_SCHED_CORE_CREATE), + ptr::without_provenance_mut(pid.as_raw_nonzero().get() as usize), + ptr::without_provenance_mut(scope as usize), ptr::null_mut(), ) .map(|_r| ()) @@ -982,9 +1050,9 @@ pub fn push_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io:: unsafe { syscalls::prctl( PR_SCHED_CORE, - PR_SCHED_CORE_SHARE_TO as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, + ptr::without_provenance_mut(PR_SCHED_CORE_SHARE_TO), + ptr::without_provenance_mut(pid.as_raw_nonzero().get() as usize), + ptr::without_provenance_mut(scope as usize), ptr::null_mut(), ) .map(|_r| ()) @@ -1004,9 +1072,9 @@ pub fn pull_core_scheduling_cookie(pid: Pid, scope: CoreSchedulingScope) -> io:: unsafe { syscalls::prctl( PR_SCHED_CORE, - PR_SCHED_CORE_SHARE_FROM as *mut _, - pid.as_raw_nonzero().get() as usize as *mut _, - scope as usize as *mut _, + ptr::without_provenance_mut(PR_SCHED_CORE_SHARE_FROM), + ptr::without_provenance_mut(pid.as_raw_nonzero().get() as usize), + ptr::without_provenance_mut(scope as usize), ptr::null_mut(), ) .map(|_r| ()) diff --git a/src/utils.rs b/src/utils.rs index 77eb26c14..d799fb7b1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -41,9 +41,7 @@ pub(crate) fn option_as_mut_ptr(t: Option<&mut T>) -> *mut T { /// misaligned, or pointing to a region of memory that wraps around the address /// space. pub(crate) fn check_raw_pointer(value: *mut c_void) -> Option> { - if (value as usize).checked_add(size_of::()).is_none() - || (value as usize) % align_of::() != 0 - { + if value.addr().checked_add(size_of::()).is_none() || value.addr() % align_of::() != 0 { return None; } diff --git a/src/weak.rs b/src/weak.rs index 036ddeea4..b03f64dc7 100644 --- a/src/weak.rs +++ b/src/weak.rs @@ -34,12 +34,12 @@ use crate::ffi::CStr; use core::ffi::c_void; -use core::ptr::null_mut; +use core::ptr::{null_mut, without_provenance_mut}; use core::sync::atomic::{self, AtomicPtr, Ordering}; use core::{marker, mem}; const NULL: *mut c_void = null_mut(); -const INVALID: *mut c_void = 1 as *mut c_void; +const INVALID: *mut c_void = without_provenance_mut(1); macro_rules! weak { ($vis:vis fn $name:ident($($t:ty),*) -> $ret:ty) => (