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
|
@ -6,7 +6,7 @@ pub fn target() -> Target {
|
|||
base.max_atomic_width = Some(128);
|
||||
|
||||
// FIXME: The leak sanitizer currently fails the tests, see #88132.
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
|
||||
|
||||
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "arm64".to_string()]);
|
||||
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> Target {
|
|||
arch: "aarch64".to_string(),
|
||||
options: TargetOptions {
|
||||
max_atomic_width: Some(128),
|
||||
supported_sanitizers: SanitizerSet::ADDRESS,
|
||||
supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI,
|
||||
..super::fuchsia_base::opts()
|
||||
},
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn target() -> Target {
|
|||
// As documented in https://developer.android.com/ndk/guides/cpu-features.html
|
||||
// the neon (ASIMD) and FP must exist on all android aarch64 targets.
|
||||
features: "+neon,+fp-armv8".to_string(),
|
||||
supported_sanitizers: SanitizerSet::HWADDRESS,
|
||||
supported_sanitizers: SanitizerSet::CFI | SanitizerSet::HWADDRESS,
|
||||
..super::android_base::opts()
|
||||
},
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ pub fn target() -> Target {
|
|||
options: TargetOptions {
|
||||
max_atomic_width: Some(128),
|
||||
supported_sanitizers: SanitizerSet::ADDRESS
|
||||
| SanitizerSet::CFI
|
||||
| SanitizerSet::MEMORY
|
||||
| SanitizerSet::THREAD,
|
||||
..super::freebsd_base::opts()
|
||||
|
|
|
@ -10,6 +10,7 @@ pub fn target() -> Target {
|
|||
mcount: "\u{1}_mcount".to_string(),
|
||||
max_atomic_width: Some(128),
|
||||
supported_sanitizers: SanitizerSet::ADDRESS
|
||||
| SanitizerSet::CFI
|
||||
| SanitizerSet::LEAK
|
||||
| SanitizerSet::MEMORY
|
||||
| SanitizerSet::THREAD
|
||||
|
|
|
@ -602,6 +602,7 @@ bitflags::bitflags! {
|
|||
const MEMORY = 1 << 2;
|
||||
const THREAD = 1 << 3;
|
||||
const HWADDRESS = 1 << 4;
|
||||
const CFI = 1 << 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -612,6 +613,7 @@ impl SanitizerSet {
|
|||
fn as_str(self) -> Option<&'static str> {
|
||||
Some(match self {
|
||||
SanitizerSet::ADDRESS => "address",
|
||||
SanitizerSet::CFI => "cfi",
|
||||
SanitizerSet::LEAK => "leak",
|
||||
SanitizerSet::MEMORY => "memory",
|
||||
SanitizerSet::THREAD => "thread",
|
||||
|
@ -644,6 +646,7 @@ impl IntoIterator for SanitizerSet {
|
|||
fn into_iter(self) -> Self::IntoIter {
|
||||
[
|
||||
SanitizerSet::ADDRESS,
|
||||
SanitizerSet::CFI,
|
||||
SanitizerSet::LEAK,
|
||||
SanitizerSet::MEMORY,
|
||||
SanitizerSet::THREAD,
|
||||
|
@ -1804,6 +1807,7 @@ impl Target {
|
|||
for s in a {
|
||||
base.$key_name |= match s.as_string() {
|
||||
Some("address") => SanitizerSet::ADDRESS,
|
||||
Some("cfi") => SanitizerSet::CFI,
|
||||
Some("leak") => SanitizerSet::LEAK,
|
||||
Some("memory") => SanitizerSet::MEMORY,
|
||||
Some("thread") => SanitizerSet::THREAD,
|
||||
|
|
|
@ -13,7 +13,8 @@ pub fn target() -> Target {
|
|||
base.link_env_remove.extend(super::apple_base::macos_link_env_remove());
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
|
||||
base.supported_sanitizers =
|
||||
SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
|
||||
|
||||
// Clang automatically chooses a more specific target based on
|
||||
// MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
|
||||
|
|
|
@ -6,7 +6,7 @@ pub fn target() -> Target {
|
|||
base.max_atomic_width = Some(64);
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-fuchsia".to_string(),
|
||||
|
|
|
@ -8,7 +8,7 @@ pub fn target() -> Target {
|
|||
base.max_atomic_width = Some(64);
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-pc-solaris".to_string(),
|
||||
|
|
|
@ -7,7 +7,8 @@ pub fn target() -> Target {
|
|||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string());
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::MEMORY | SanitizerSet::THREAD;
|
||||
base.supported_sanitizers =
|
||||
SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::MEMORY | SanitizerSet::THREAD;
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-unknown-freebsd".to_string(),
|
||||
|
|
|
@ -5,7 +5,7 @@ pub fn target() -> Target {
|
|||
base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-m64".to_string(), "-std=c99".to_string()]);
|
||||
base.cpu = "x86-64".to_string();
|
||||
base.max_atomic_width = Some(64);
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI;
|
||||
|
||||
Target {
|
||||
// LLVM does not currently have a separate illumos target,
|
||||
|
|
|
@ -7,8 +7,11 @@ pub fn target() -> Target {
|
|||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string());
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers =
|
||||
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS
|
||||
| SanitizerSet::CFI
|
||||
| SanitizerSet::LEAK
|
||||
| SanitizerSet::MEMORY
|
||||
| SanitizerSet::THREAD;
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-unknown-linux-gnu".to_string(),
|
||||
|
|
|
@ -8,8 +8,11 @@ pub fn target() -> Target {
|
|||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.static_position_independent_executables = true;
|
||||
base.supported_sanitizers =
|
||||
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS
|
||||
| SanitizerSet::CFI
|
||||
| SanitizerSet::LEAK
|
||||
| SanitizerSet::MEMORY
|
||||
| SanitizerSet::THREAD;
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-unknown-linux-musl".to_string(),
|
||||
|
|
|
@ -7,8 +7,11 @@ pub fn target() -> Target {
|
|||
base.pre_link_args.entry(LinkerFlavor::Gcc).or_default().push("-m64".to_string());
|
||||
// don't use probe-stack=inline-asm until rust#83139 and rust#84667 are resolved
|
||||
base.stack_probes = StackProbeType::Call;
|
||||
base.supported_sanitizers =
|
||||
SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
|
||||
base.supported_sanitizers = SanitizerSet::ADDRESS
|
||||
| SanitizerSet::CFI
|
||||
| SanitizerSet::LEAK
|
||||
| SanitizerSet::MEMORY
|
||||
| SanitizerSet::THREAD;
|
||||
|
||||
Target {
|
||||
llvm_target: "x86_64-unknown-netbsd".to_string(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue