diff --git a/library/core/src/fmt/rt.rs b/library/core/src/fmt/rt.rs index d37888c27bde3..5bf221b429fac 100644 --- a/library/core/src/fmt/rt.rs +++ b/library/core/src/fmt/rt.rs @@ -133,6 +133,10 @@ impl<'a> Argument<'a> { Self::new(x, USIZE_MARKER) } + // FIXME: Transmuting formatter in new and indirectly branching to/calling + // it here is an explicit CFI violation. + #[allow(inline_no_sanitize)] + #[no_sanitize(cfi, kcfi)] #[inline(always)] pub(super) fn fmt(&self, f: &mut Formatter<'_>) -> Result { (self.formatter)(self.value, f) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index ab8d9f33b08b4..7fa7e83a74429 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -238,6 +238,7 @@ #![feature(negative_impls)] #![feature(never_type)] #![feature(no_core)] +#![feature(no_sanitize)] #![feature(platform_intrinsics)] #![feature(prelude_import)] #![feature(repr_simd)] diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 6f78778f01a54..02f4d5bc7ae14 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -270,6 +270,7 @@ #![feature(allow_internal_unstable)] #![feature(c_unwind)] #![feature(cfg_target_thread_local)] +#![feature(cfi_encoding)] #![feature(concat_idents)] #![feature(const_mut_refs)] #![feature(const_trait_impl)] @@ -292,6 +293,7 @@ #![feature(needs_panic_runtime)] #![feature(negative_impls)] #![feature(never_type)] +#![feature(no_sanitize)] #![feature(platform_intrinsics)] #![feature(prelude_import)] #![feature(rustc_attrs)] diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs index fba2a676f280f..e9d19766592c8 100644 --- a/library/std/src/sys/unix/thread_local_dtor.rs +++ b/library/std/src/sys/unix/thread_local_dtor.rs @@ -11,28 +11,47 @@ // Note, however, that we run on lots older linuxes, as well as cross // compiling from a newer linux to an older linux, so we also have a // fallback implementation to use as well. +#[allow(unexpected_cfgs)] #[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox", target_os = "hurd"))] +// FIXME: The Rust compiler currently omits weakly function definitions (i.e., +// __cxa_thread_atexit_impl) and its metadata from LLVM IR. +#[no_sanitize(cfi, kcfi)] pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) { use crate::mem; use crate::sys_common::thread_local_dtor::register_dtor_fallback; + /// This is necessary because the __cxa_thread_atexit_impl implementation + /// std links to by default may be a C or C++ implementation that was not + /// compiled using the Clang integer normalization option. + #[cfg(not(sanitizer_cfi_normalize_integers))] + #[cfi_encoding = "i"] + #[repr(transparent)] + pub struct c_int(pub libc::c_int); + extern "C" { #[linkage = "extern_weak"] static __dso_handle: *mut u8; #[linkage = "extern_weak"] - static __cxa_thread_atexit_impl: *const libc::c_void; + static __cxa_thread_atexit_impl: Option< + extern "C" fn( + unsafe extern "C" fn(*mut libc::c_void), + *mut libc::c_void, + *mut libc::c_void, + ) -> c_int, + >; } - if !__cxa_thread_atexit_impl.is_null() { - type F = unsafe extern "C" fn( - dtor: unsafe extern "C" fn(*mut u8), - arg: *mut u8, - dso_handle: *mut u8, - ) -> libc::c_int; - mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)( - dtor, - t, - &__dso_handle as *const _ as *mut _, - ); + + if let Some(f) = __cxa_thread_atexit_impl { + unsafe { + f( + mem::transmute::< + unsafe extern "C" fn(*mut u8), + unsafe extern "C" fn(*mut libc::c_void), + >(dtor), + t.cast(), + &__dso_handle as *const _ as *mut _, + ); + } return; } register_dtor_fallback(t, dtor);