Skip to content

Commit

Permalink
Add support for full RELRO
Browse files Browse the repository at this point in the history
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 #29877.

Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
  • Loading branch information
kyrias committed Jul 11, 2017
1 parent 1999bfa commit 2306687
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/librustc_back/target/bitrig_base.rs
Expand Up @@ -19,6 +19,7 @@ pub fn opts() -> TargetOptions {
linker_is_gnu: true,
has_rpath: true,
position_independent_executables: true,
full_relro: true,

.. Default::default()
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/dragonfly_base.rs
Expand Up @@ -33,6 +33,7 @@ pub fn opts() -> TargetOptions {
has_rpath: true,
pre_link_args: args,
position_independent_executables: true,
full_relro: true,
exe_allocation_crate: super::maybe_jemalloc(),
.. Default::default()
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/freebsd_base.rs
Expand Up @@ -33,6 +33,7 @@ pub fn opts() -> TargetOptions {
has_rpath: true,
pre_link_args: args,
position_independent_executables: true,
full_relro: true,
exe_allocation_crate: super::maybe_jemalloc(),
.. Default::default()
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/haiku_base.rs
Expand Up @@ -18,6 +18,7 @@ pub fn opts() -> TargetOptions {
executables: true,
has_rpath: false,
target_family: Some("unix".to_string()),
full_relro: true,
linker_is_gnu: true,
no_integrated_as: true,
.. Default::default()
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/linux_base.rs
Expand Up @@ -36,6 +36,7 @@ pub fn opts() -> TargetOptions {
has_rpath: true,
pre_link_args: args,
position_independent_executables: true,
full_relro: true,
exe_allocation_crate: super::maybe_jemalloc(),
has_elf_tls: true,
.. Default::default()
Expand Down
6 changes: 6 additions & 0 deletions src/librustc_back/target/mod.rs
Expand Up @@ -367,6 +367,9 @@ pub struct TargetOptions {
/// the functions in the executable are not randomized and can be used
/// during an exploit of a vulnerability in any code.
pub position_independent_executables: bool,
/// Full RELRO makes the dynamic linker resolve all symbols at startup and marks the GOT
/// read-only before starting the program, preventing overwriting the GOT.
pub full_relro: bool,
/// Format that archives should be emitted in. This affects whether we use
/// LLVM to assemble an archive or fall back to the system linker, and
/// currently only "gnu" is used to fall into LLVM. Unknown strings cause
Expand Down Expand Up @@ -454,6 +457,7 @@ impl Default for TargetOptions {
has_rpath: false,
no_default_libraries: true,
position_independent_executables: false,
full_relro: false,
pre_link_objects_exe: Vec::new(),
pre_link_objects_dll: Vec::new(),
post_link_objects: Vec::new(),
Expand Down Expand Up @@ -683,6 +687,7 @@ impl Target {
key!(has_rpath, bool);
key!(no_default_libraries, bool);
key!(position_independent_executables, bool);
key!(full_relro, bool);
key!(archive_format);
key!(allow_asm, bool);
key!(custom_unwind_resume, bool);
Expand Down Expand Up @@ -870,6 +875,7 @@ impl ToJson for Target {
target_option_val!(has_rpath);
target_option_val!(no_default_libraries);
target_option_val!(position_independent_executables);
target_option_val!(full_relro);
target_option_val!(archive_format);
target_option_val!(allow_asm);
target_option_val!(custom_unwind_resume);
Expand Down
1 change: 1 addition & 0 deletions src/librustc_back/target/netbsd_base.rs
Expand Up @@ -33,6 +33,7 @@ pub fn opts() -> TargetOptions {
has_rpath: true,
pre_link_args: args,
position_independent_executables: true,
full_relro: true,
.. Default::default()
}
}
1 change: 1 addition & 0 deletions src/librustc_back/target/openbsd_base.rs
Expand Up @@ -34,6 +34,7 @@ pub fn opts() -> TargetOptions {
is_like_openbsd: true,
pre_link_args: args,
position_independent_executables: true,
full_relro: true,
.. Default::default()
}
}
4 changes: 4 additions & 0 deletions src/librustc_trans/back/link.rs
Expand Up @@ -1029,6 +1029,10 @@ fn link_args(cmd: &mut Linker,
}
}

if t.options.full_relro {
cmd.full_relro();
}

// Pass optimization flags down to the linker.
cmd.optimize();

Expand Down
10 changes: 10 additions & 0 deletions src/librustc_trans/back/linker.rs
Expand Up @@ -104,6 +104,7 @@ pub trait Linker {
fn add_object(&mut self, path: &Path);
fn gc_sections(&mut self, keep_metadata: bool);
fn position_independent_executable(&mut self);
fn full_relro(&mut self);
fn optimize(&mut self);
fn debuginfo(&mut self);
fn no_default_libraries(&mut self);
Expand Down Expand Up @@ -175,6 +176,7 @@ impl<'a> Linker for GccLinker<'a> {
fn output_filename(&mut self, path: &Path) { self.cmd.arg("-o").arg(path); }
fn add_object(&mut self, path: &Path) { self.cmd.arg(path); }
fn position_independent_executable(&mut self) { self.cmd.arg("-pie"); }
fn full_relro(&mut self) { self.linker_arg("-z,relro,-z,now"); }
fn args(&mut self, args: &[String]) { self.cmd.args(args); }

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

fn full_relro(&mut self) {
// noop
}

fn no_default_libraries(&mut self) {
// Currently we don't pass the /NODEFAULTLIB flag to the linker on MSVC
// as there's been trouble in the past of linking the C++ standard
Expand Down Expand Up @@ -595,6 +601,10 @@ impl<'a> Linker for EmLinker<'a> {
// noop
}

fn full_relro(&mut self) {
// noop
}

fn args(&mut self, args: &[String]) {
self.cmd.args(args);
}
Expand Down

0 comments on commit 2306687

Please sign in to comment.