Disable CFI for core and std CFI violations

Works around #115199 by temporarily disabling CFI for core and std CFI
violations to allow the user rebuild and use both core and std with CFI
enabled using the Cargo build-std feature.
This commit is contained in:
Ramon de C Valle 2023-08-24 17:09:15 -07:00
parent 2ffeb4636b
commit 7b45674015
4 changed files with 38 additions and 12 deletions

View File

@ -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)

View File

@ -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)]

View File

@ -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)]

View File

@ -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);