Auto merge of #89652 - rcvalle:rust-cfi, r=nagisa
Add LLVM CFI support to the Rust compiler This PR adds LLVM Control Flow Integrity (CFI) support to the Rust compiler. It initially provides forward-edge control flow protection for Rust-compiled code only by aggregating function pointers in groups identified by their number of arguments. Forward-edge control flow protection for C or C++ and Rust -compiled code "mixed binaries" (i.e., for when C or C++ and Rust -compiled code share the same virtual address space) will be provided in later work as part of this project by defining and using compatible type identifiers (see Type metadata in the design document in the tracking issue #89653). LLVM CFI can be enabled with -Zsanitizer=cfi and requires LTO (i.e., -Clto). Thank you, `@eddyb` and `@pcc,` for all the help!
This commit is contained in:
commit
a8f6e614f8
35 changed files with 473 additions and 39 deletions
|
@ -104,8 +104,9 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
|||
use rustc_middle::mir::mono::{InstantiationMode, MonoItem};
|
||||
use rustc_middle::ty::query::Providers;
|
||||
use rustc_middle::ty::subst::SubstsRef;
|
||||
use rustc_middle::ty::{self, Instance, TyCtxt};
|
||||
use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
|
||||
use rustc_session::config::SymbolManglingVersion;
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
|
||||
use tracing::debug;
|
||||
|
||||
|
@ -151,6 +152,11 @@ fn symbol_name_provider(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) -> ty::Symb
|
|||
ty::SymbolName::new(tcx, &symbol_name)
|
||||
}
|
||||
|
||||
/// This function computes the typeid for the given function ABI.
|
||||
pub fn typeid_for_fnabi(tcx: TyCtxt<'tcx>, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> String {
|
||||
v0::mangle_typeid_for_fnabi(tcx, fn_abi)
|
||||
}
|
||||
|
||||
/// Computes the symbol name for the given instance. This function will call
|
||||
/// `compute_instantiating_crate` if it needs to factor the instantiating crate
|
||||
/// into the symbol name.
|
||||
|
|
|
@ -9,6 +9,7 @@ use rustc_middle::ty::layout::IntegerExt;
|
|||
use rustc_middle::ty::print::{Print, Printer};
|
||||
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy};
|
||||
use rustc_target::abi::call::FnAbi;
|
||||
use rustc_target::abi::Integer;
|
||||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
|
@ -55,6 +56,41 @@ pub(super) fn mangle(
|
|||
std::mem::take(&mut cx.out)
|
||||
}
|
||||
|
||||
pub(super) fn mangle_typeid_for_fnabi(
|
||||
_tcx: TyCtxt<'tcx>,
|
||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
) -> String {
|
||||
// LLVM uses type metadata to allow IR modules to aggregate pointers by their types.[1] This
|
||||
// type metadata is used by LLVM Control Flow Integrity to test whether a given pointer is
|
||||
// associated with a type identifier (i.e., test type membership).
|
||||
//
|
||||
// Clang uses the Itanium C++ ABI's[2] virtual tables and RTTI typeinfo structure name[3] as
|
||||
// type metadata identifiers for function pointers. The typeinfo name encoding is a
|
||||
// two-character code (i.e., “TS”) prefixed to the type encoding for the function.
|
||||
//
|
||||
// For cross-language LLVM CFI support, a compatible encoding must be used by either
|
||||
//
|
||||
// a. Using a superset of types that encompasses types used by Clang (i.e., Itanium C++ ABI's
|
||||
// type encodings[4]), or at least types used at the FFI boundary.
|
||||
// b. Reducing the types to the least common denominator between types used by Clang (or at
|
||||
// least types used at the FFI boundary) and Rust compilers (if even possible).
|
||||
// c. Creating a new ABI for cross-language CFI and using it for Clang and Rust compilers (and
|
||||
// possibly other compilers).
|
||||
//
|
||||
// Option (b) may weaken the protection for Rust-compiled only code, so it should be provided
|
||||
// as an alternative to a Rust-specific encoding for when mixing Rust and C and C++ -compiled
|
||||
// code. Option (c) would require changes to Clang to use the new ABI.
|
||||
//
|
||||
// [1] https://llvm.org/docs/TypeMetadata.html
|
||||
// [2] https://itanium-cxx-abi.github.io/cxx-abi/abi.html
|
||||
// [3] https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-special-vtables
|
||||
// [4] https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-type
|
||||
//
|
||||
// FIXME(rcvalle): See comment above.
|
||||
let arg_count = fn_abi.args.len() + fn_abi.ret.is_indirect() as usize;
|
||||
format!("typeid{}", arg_count)
|
||||
}
|
||||
|
||||
struct BinderLevel {
|
||||
/// The range of distances from the root of what's
|
||||
/// being printed, to the lifetimes in a binder.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue