Skip to content

Commit cb0e0db

Browse files
committed
Auto merge of #83619 - petrochenkov:nx, r=nagisa
linker: Use data execution prevention options by default when linker supports them Do it in a centralized way in `link.rs` instead of individual target specs. r? `@nagisa`
2 parents 4a20eb6 + cc5392e commit cb0e0db

11 files changed

+23
-73
lines changed

compiler/rustc_codegen_ssa/src/back/link.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1651,6 +1651,10 @@ fn linker_with_args<'a, B: ArchiveBuilder<'a>>(
16511651
cmd.add_eh_frame_header();
16521652
}
16531653

1654+
// NO-OPT-OUT, OBJECT-FILES-NO, AUDIT-ORDER
1655+
// Make the binary compatible with data execution prevention schemes.
1656+
cmd.add_no_exec();
1657+
16541658
// NO-OPT-OUT, OBJECT-FILES-NO
16551659
// Avoid linking to dynamic libraries unless they satisfy some undefined symbols
16561660
// at the point at which they are specified on the command line.

compiler/rustc_codegen_ssa/src/back/linker.rs

+13
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ pub trait Linker {
130130
fn group_end(&mut self);
131131
fn linker_plugin_lto(&mut self);
132132
fn add_eh_frame_header(&mut self) {}
133+
fn add_no_exec(&mut self) {}
133134
fn add_as_needed(&mut self) {}
134135
fn finalize(&mut self);
135136
}
@@ -643,6 +644,14 @@ impl<'a> Linker for GccLinker<'a> {
643644
self.linker_arg("--eh-frame-hdr");
644645
}
645646

647+
fn add_no_exec(&mut self) {
648+
if self.sess.target.is_like_windows {
649+
self.linker_arg("--nxcompat");
650+
} else if self.sess.target.linker_is_gnu {
651+
self.linker_arg("-znoexecstack");
652+
}
653+
}
654+
646655
fn add_as_needed(&mut self) {
647656
if self.sess.target.linker_is_gnu {
648657
self.linker_arg("--as-needed");
@@ -885,6 +894,10 @@ impl<'a> Linker for MsvcLinker<'a> {
885894
fn linker_plugin_lto(&mut self) {
886895
// Do nothing
887896
}
897+
898+
fn add_no_exec(&mut self) {
899+
self.cmd.arg("/NXCOMPAT");
900+
}
888901
}
889902

890903
pub struct EmLinker<'a> {

compiler/rustc_target/src/spec/dragonfly_base.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
1-
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
1+
use crate::spec::{RelroLevel, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
4-
let mut args = LinkArgs::new();
5-
args.insert(
6-
LinkerFlavor::Gcc,
7-
vec![
8-
// Always enable NX protection when it is available
9-
"-Wl,-z,noexecstack".to_string(),
10-
],
11-
);
12-
134
TargetOptions {
145
os: "dragonfly".to_string(),
156
dynamic_linking: true,
167
executables: true,
178
os_family: Some("unix".to_string()),
189
linker_is_gnu: true,
1910
has_rpath: true,
20-
pre_link_args: args,
2111
position_independent_executables: true,
2212
relro_level: RelroLevel::Full,
2313
dwarf_version: Some(2),

compiler/rustc_target/src/spec/freebsd_base.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
1-
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
1+
use crate::spec::{RelroLevel, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
4-
let mut args = LinkArgs::new();
5-
args.insert(
6-
LinkerFlavor::Gcc,
7-
vec![
8-
// Always enable NX protection when it is available
9-
"-Wl,-z,noexecstack".to_string(),
10-
],
11-
);
12-
134
TargetOptions {
145
os: "freebsd".to_string(),
156
dynamic_linking: true,
167
executables: true,
178
os_family: Some("unix".to_string()),
189
linker_is_gnu: true,
1910
has_rpath: true,
20-
pre_link_args: args,
2111
position_independent_executables: true,
2212
eliminate_frame_pointer: false, // FIXME 43575
2313
relro_level: RelroLevel::Full,

compiler/rustc_target/src/spec/linux_base.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
1-
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
1+
use crate::spec::{RelroLevel, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
4-
let mut args = LinkArgs::new();
5-
args.insert(
6-
LinkerFlavor::Gcc,
7-
vec![
8-
// Always enable NX protection when it is available
9-
"-Wl,-z,noexecstack".to_string(),
10-
],
11-
);
12-
134
TargetOptions {
145
os: "linux".to_string(),
156
dynamic_linking: true,
167
executables: true,
178
os_family: Some("unix".to_string()),
189
linker_is_gnu: true,
1910
has_rpath: true,
20-
pre_link_args: args,
2111
position_independent_executables: true,
2212
relro_level: RelroLevel::Full,
2313
has_elf_tls: true,

compiler/rustc_target/src/spec/linux_kernel_base.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
1-
use crate::spec::{
2-
LinkArgs, LinkerFlavor, PanicStrategy, RelocModel, RelroLevel, StackProbeType, TargetOptions,
3-
};
1+
use crate::spec::{PanicStrategy, RelocModel, RelroLevel, StackProbeType, TargetOptions};
42

53
pub fn opts() -> TargetOptions {
6-
let mut pre_link_args = LinkArgs::new();
7-
pre_link_args.insert(LinkerFlavor::Gcc, vec!["-Wl,-z,noexecstack".to_string()]);
8-
94
TargetOptions {
105
env: "gnu".to_string(),
116
disable_redzone: true,
@@ -17,7 +12,6 @@ pub fn opts() -> TargetOptions {
1712
needs_plt: true,
1813
relro_level: RelroLevel::Full,
1914
relocation_model: RelocModel::Static,
20-
pre_link_args,
2115

2216
..Default::default()
2317
}

compiler/rustc_target/src/spec/msvc_base.rs

-7
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,6 @@ pub fn opts() -> TargetOptions {
55
// Suppress the verbose logo and authorship debugging output, which would needlessly
66
// clog any log files.
77
"/NOLOGO".to_string(),
8-
// Tell the compiler that non-code sections can be marked as non-executable,
9-
// including stack pages.
10-
// UEFI is fully compatible to non-executable data pages.
11-
// In fact, firmware might enforce this, so we better let the linker know about this,
12-
// so it will fail if the compiler ever tries placing code on the stack
13-
// (e.g., trampoline constructs and alike).
14-
"/NXCOMPAT".to_string(),
158
];
169
let mut pre_link_args = LinkArgs::new();
1710
pre_link_args.insert(LinkerFlavor::Msvc, pre_link_args_msvc.clone());

compiler/rustc_target/src/spec/openbsd_base.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
1+
use crate::spec::{RelroLevel, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
4-
let mut args = LinkArgs::new();
5-
args.insert(
6-
LinkerFlavor::Gcc,
7-
vec![
8-
// Always enable NX protection when it is available
9-
"-Wl,-z,noexecstack".to_string(),
10-
],
11-
);
12-
134
TargetOptions {
145
os: "openbsd".to_string(),
156
dynamic_linking: true,
@@ -18,7 +9,6 @@ pub fn opts() -> TargetOptions {
189
linker_is_gnu: true,
1910
has_rpath: true,
2011
abi_return_struct_as_int: true,
21-
pre_link_args: args,
2212
position_independent_executables: true,
2313
eliminate_frame_pointer: false, // FIXME 43575
2414
relro_level: RelroLevel::Full,

compiler/rustc_target/src/spec/redox_base.rs

+1-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
use crate::spec::{LinkArgs, LinkerFlavor, RelroLevel, TargetOptions};
1+
use crate::spec::{RelroLevel, TargetOptions};
22

33
pub fn opts() -> TargetOptions {
4-
let mut args = LinkArgs::new();
5-
args.insert(
6-
LinkerFlavor::Gcc,
7-
vec![
8-
// Always enable NX protection when it is available
9-
"-Wl,-z,noexecstack".to_string(),
10-
],
11-
);
12-
134
TargetOptions {
145
os: "redox".to_string(),
156
env: "relibc".to_string(),
@@ -18,7 +9,6 @@ pub fn opts() -> TargetOptions {
189
os_family: Some("unix".to_string()),
1910
linker_is_gnu: true,
2011
has_rpath: true,
21-
pre_link_args: args,
2212
position_independent_executables: true,
2313
relro_level: RelroLevel::Full,
2414
has_elf_tls: true,

compiler/rustc_target/src/spec/windows_gnu_base.rs

-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ pub fn opts() -> TargetOptions {
99
// Tell GCC to avoid linker plugins, because we are not bundling
1010
// them with Windows installer, and Rust does its own LTO anyways.
1111
"-fno-use-linker-plugin".to_string(),
12-
// Always enable DEP (NX bit) when it is available
13-
"-Wl,--nxcompat".to_string(),
1412
// Enable ASLR
1513
"-Wl,--dynamicbase".to_string(),
1614
// ASLR will rebase it anyway so leaving that option enabled only leads to confusion

compiler/rustc_target/src/spec/x86_64_fortanix_unknown_sgx.rs

-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ use super::{LinkerFlavor, LldFlavor, PanicStrategy, Target, TargetOptions};
44

55
pub fn target() -> Target {
66
const PRE_LINK_ARGS: &[&str] = &[
7-
"-z",
8-
"noexecstack",
97
"-e",
108
"elf_entry",
119
"-Bstatic",

0 commit comments

Comments
 (0)