Skip to content

Commit 2306687

Browse files
committed
Add support for full RELRO
This commit adds support for full RELRO, and enables it for the platforms I know have support for it. Full RELRO makes the PLT+GOT data read-only on startup, preventing it from being overwritten. http://tk-blog.blogspot.com/2009/02/relro-not-so-well-known-memory.html Fixes rust-lang#29877. Signed-off-by: Johannes Löthberg <[email protected]>
1 parent 1999bfa commit 2306687

File tree

10 files changed

+27
-0
lines changed

10 files changed

+27
-0
lines changed

src/librustc_back/target/bitrig_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn opts() -> TargetOptions {
1919
linker_is_gnu: true,
2020
has_rpath: true,
2121
position_independent_executables: true,
22+
full_relro: true,
2223

2324
.. Default::default()
2425
}

src/librustc_back/target/dragonfly_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub fn opts() -> TargetOptions {
3333
has_rpath: true,
3434
pre_link_args: args,
3535
position_independent_executables: true,
36+
full_relro: true,
3637
exe_allocation_crate: super::maybe_jemalloc(),
3738
.. Default::default()
3839
}

src/librustc_back/target/freebsd_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub fn opts() -> TargetOptions {
3333
has_rpath: true,
3434
pre_link_args: args,
3535
position_independent_executables: true,
36+
full_relro: true,
3637
exe_allocation_crate: super::maybe_jemalloc(),
3738
.. Default::default()
3839
}

src/librustc_back/target/haiku_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub fn opts() -> TargetOptions {
1818
executables: true,
1919
has_rpath: false,
2020
target_family: Some("unix".to_string()),
21+
full_relro: true,
2122
linker_is_gnu: true,
2223
no_integrated_as: true,
2324
.. Default::default()

src/librustc_back/target/linux_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub fn opts() -> TargetOptions {
3636
has_rpath: true,
3737
pre_link_args: args,
3838
position_independent_executables: true,
39+
full_relro: true,
3940
exe_allocation_crate: super::maybe_jemalloc(),
4041
has_elf_tls: true,
4142
.. Default::default()

src/librustc_back/target/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,9 @@ pub struct TargetOptions {
367367
/// the functions in the executable are not randomized and can be used
368368
/// during an exploit of a vulnerability in any code.
369369
pub position_independent_executables: bool,
370+
/// Full RELRO makes the dynamic linker resolve all symbols at startup and marks the GOT
371+
/// read-only before starting the program, preventing overwriting the GOT.
372+
pub full_relro: bool,
370373
/// Format that archives should be emitted in. This affects whether we use
371374
/// LLVM to assemble an archive or fall back to the system linker, and
372375
/// currently only "gnu" is used to fall into LLVM. Unknown strings cause
@@ -454,6 +457,7 @@ impl Default for TargetOptions {
454457
has_rpath: false,
455458
no_default_libraries: true,
456459
position_independent_executables: false,
460+
full_relro: false,
457461
pre_link_objects_exe: Vec::new(),
458462
pre_link_objects_dll: Vec::new(),
459463
post_link_objects: Vec::new(),
@@ -683,6 +687,7 @@ impl Target {
683687
key!(has_rpath, bool);
684688
key!(no_default_libraries, bool);
685689
key!(position_independent_executables, bool);
690+
key!(full_relro, bool);
686691
key!(archive_format);
687692
key!(allow_asm, bool);
688693
key!(custom_unwind_resume, bool);
@@ -870,6 +875,7 @@ impl ToJson for Target {
870875
target_option_val!(has_rpath);
871876
target_option_val!(no_default_libraries);
872877
target_option_val!(position_independent_executables);
878+
target_option_val!(full_relro);
873879
target_option_val!(archive_format);
874880
target_option_val!(allow_asm);
875881
target_option_val!(custom_unwind_resume);

src/librustc_back/target/netbsd_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ pub fn opts() -> TargetOptions {
3333
has_rpath: true,
3434
pre_link_args: args,
3535
position_independent_executables: true,
36+
full_relro: true,
3637
.. Default::default()
3738
}
3839
}

src/librustc_back/target/openbsd_base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub fn opts() -> TargetOptions {
3434
is_like_openbsd: true,
3535
pre_link_args: args,
3636
position_independent_executables: true,
37+
full_relro: true,
3738
.. Default::default()
3839
}
3940
}

src/librustc_trans/back/link.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,6 +1029,10 @@ fn link_args(cmd: &mut Linker,
10291029
}
10301030
}
10311031

1032+
if t.options.full_relro {
1033+
cmd.full_relro();
1034+
}
1035+
10321036
// Pass optimization flags down to the linker.
10331037
cmd.optimize();
10341038

src/librustc_trans/back/linker.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ pub trait Linker {
104104
fn add_object(&mut self, path: &Path);
105105
fn gc_sections(&mut self, keep_metadata: bool);
106106
fn position_independent_executable(&mut self);
107+
fn full_relro(&mut self);
107108
fn optimize(&mut self);
108109
fn debuginfo(&mut self);
109110
fn no_default_libraries(&mut self);
@@ -175,6 +176,7 @@ impl<'a> Linker for GccLinker<'a> {
175176
fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); }
176177
fn add_object(&mut self, path: &Path) { self.cmd.arg(path); }
177178
fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
179+
fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
178180
fn args(&mut self, args: &[String]) { self.cmd.args(args); }
179181

180182
fn link_rust_dylib(&mut self, lib: &str, _path: &Path) {
@@ -428,6 +430,10 @@ impl<'a> Linker for MsvcLinker<'a> {
428430
// noop
429431
}
430432

433+
fn full_relro(&mut self) {
434+
// noop
435+
}
436+
431437
fn no_default_libraries(&mut self) {
432438
// Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC
433439
// as there's been trouble in the past of linking the C++ standard
@@ -595,6 +601,10 @@ impl<'a> Linker for EmLinker<'a> {
595601
// noop
596602
}
597603

604+
fn full_relro(&mut self) {
605+
// noop
606+
}
607+
598608
fn args(&mut self, args: &[String]) {
599609
self.cmd.args(args);
600610
}

0 commit comments

Comments
 (0)