From 02bb2d4410d4db07c40bed308f8ba0d2af28d069 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Tue, 4 Mar 2025 14:31:03 +0000 Subject: [PATCH 1/2] Disable CFI for weakly linked syscalls Currently, when enabling CFI via -Zsanitizer=cfi and executing e.g. std::sys::random::getrandom, we can observe a CFI violation. This is the case for all consumers of the std::sys::pal::weak::weak macro, as it is defining weak functions which don't show up in LLVM IR metadata. CFI fails for all these functions. Similar to other such cases in https://github.com/rust-lang/rust/issues/115199, this change stops emitting the CFI typecheck for consumers of the macro via the \#[no_sanitize(cfi)] attribute. --- library/std/src/sys/fs/unix.rs | 12 ++++++++++++ library/std/src/sys/pal/unix/fd.rs | 1 + library/std/src/sys/pal/unix/process/process_unix.rs | 1 + library/std/src/sys/pal/unix/thread.rs | 1 + library/std/src/sys/pal/unix/time.rs | 9 +++++++++ library/std/src/sys/pal/unix/weak.rs | 3 +++ 6 files changed, 27 insertions(+) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 914971934bfb0..d95735978c199 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1454,6 +1454,18 @@ impl File { Ok(()) } + #[cfg_attr( + any( + target_os = "android", + all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ) + ), + no_sanitize(cfi) + )] pub fn set_times(&self, times: FileTimes) -> io::Result<()> { #[cfg(not(any( target_os = "redox", diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs index 2fc33bdfefbf5..6da329288f746 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/pal/unix/fd.rs @@ -251,6 +251,7 @@ impl FileDesc { } #[cfg(all(target_os = "android", target_pointer_width = "32"))] + #[no_sanitize(cfi)] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 25d9e9353320f..6d3680d231e6b 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -434,6 +434,7 @@ impl Command { target_os = "nto", target_vendor = "apple", ))] + #[cfg_attr(target_os = "linux", no_sanitize(cfi))] fn posix_spawn( &mut self, stdio: &ChildPipes, diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 11f6998cac118..33db8e6939a4d 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -188,6 +188,7 @@ impl Thread { } #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))] + #[no_sanitize(cfi)] pub fn set_name(name: &CStr) { weak! { fn pthread_setname_np( diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index 0271626380c5f..fc60c307f34e1 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -96,6 +96,15 @@ impl Timespec { } } + #[cfg_attr( + all( + target_os = "linux", + target_env = "gnu", + target_pointer_width = "32", + not(target_arch = "riscv32") + ), + no_sanitize(cfi) + )] pub fn now(clock: libc::clockid_t) -> Timespec { use crate::mem::MaybeUninit; use crate::sys::cvt; diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index 7ec4787f1eab7..9a718b71f4696 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -144,6 +144,9 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void { #[cfg(not(any(target_os = "linux", target_os = "android")))] pub(crate) macro syscall { (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( + // FIXME: Rust currently omits weak function definitions + // and its metadata from LLVM IR. + #[no_sanitize(cfi)] unsafe fn $name($($arg_name: $t),*) -> $ret { weak! { fn $name($($t),*) -> $ret } From e5dc1e378619b11b296a953ca08abb2cdf38f9e0 Mon Sep 17 00:00:00 2001 From: Bastian Kersting Date: Mon, 10 Mar 2025 08:59:24 +0000 Subject: [PATCH 2/2] Add comments for #[no_sanitize(cfi)] in stdlib --- library/std/src/sys/fs/unix.rs | 2 ++ library/std/src/sys/pal/unix/fd.rs | 2 ++ library/std/src/sys/pal/unix/process/process_unix.rs | 2 ++ library/std/src/sys/pal/unix/thread.rs | 2 ++ library/std/src/sys/pal/unix/time.rs | 2 ++ library/std/src/sys/pal/unix/weak.rs | 2 +- 6 files changed, 11 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index d95735978c199..d944bc9c9a2a0 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1454,6 +1454,8 @@ impl File { Ok(()) } + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[cfg_attr( any( target_os = "android", diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs index 6da329288f746..a08c7ccec2da3 100644 --- a/library/std/src/sys/pal/unix/fd.rs +++ b/library/std/src/sys/pal/unix/fd.rs @@ -251,6 +251,8 @@ impl FileDesc { } #[cfg(all(target_os = "android", target_pointer_width = "32"))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[no_sanitize(cfi)] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { super::weak::weak!(fn preadv64(libc::c_int, *const libc::iovec, libc::c_int, off64_t) -> isize); diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs index 6d3680d231e6b..be9a7e919905f 100644 --- a/library/std/src/sys/pal/unix/process/process_unix.rs +++ b/library/std/src/sys/pal/unix/process/process_unix.rs @@ -434,6 +434,8 @@ impl Command { target_os = "nto", target_vendor = "apple", ))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[cfg_attr(target_os = "linux", no_sanitize(cfi))] fn posix_spawn( &mut self, diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs index 33db8e6939a4d..abe8d3fbf681e 100644 --- a/library/std/src/sys/pal/unix/thread.rs +++ b/library/std/src/sys/pal/unix/thread.rs @@ -188,6 +188,8 @@ impl Thread { } #[cfg(any(target_os = "solaris", target_os = "illumos", target_os = "nto"))] + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[no_sanitize(cfi)] pub fn set_name(name: &CStr) { weak! { diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs index fc60c307f34e1..c0a3044660b7e 100644 --- a/library/std/src/sys/pal/unix/time.rs +++ b/library/std/src/sys/pal/unix/time.rs @@ -96,6 +96,8 @@ impl Timespec { } } + // FIXME(#115199): Rust currently omits weak function definitions + // and its metadata from LLVM IR. #[cfg_attr( all( target_os = "linux", diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs index 9a718b71f4696..ce3f66a83748b 100644 --- a/library/std/src/sys/pal/unix/weak.rs +++ b/library/std/src/sys/pal/unix/weak.rs @@ -144,7 +144,7 @@ unsafe fn fetch(name: &str) -> *mut libc::c_void { #[cfg(not(any(target_os = "linux", target_os = "android")))] pub(crate) macro syscall { (fn $name:ident($($arg_name:ident: $t:ty),*) -> $ret:ty) => ( - // FIXME: Rust currently omits weak function definitions + // FIXME(#115199): Rust currently omits weak function definitions // and its metadata from LLVM IR. #[no_sanitize(cfi)] unsafe fn $name($($arg_name: $t),*) -> $ret {