]> git.lizzy.rs Git - rust.git/commitdiff
Add support for full RELRO
authorJohannes Löthberg <johannes@kyriasis.com>
Mon, 10 Jul 2017 18:57:45 +0000 (20:57 +0200)
committerJohannes Löthberg <johannes@kyriasis.com>
Tue, 11 Jul 2017 12:22:12 +0000 (14:22 +0200)
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/rust#29877.

Signed-off-by: Johannes Löthberg <johannes@kyriasis.com>
src/librustc_back/target/bitrig_base.rs
src/librustc_back/target/dragonfly_base.rs
src/librustc_back/target/freebsd_base.rs
src/librustc_back/target/haiku_base.rs
src/librustc_back/target/linux_base.rs
src/librustc_back/target/mod.rs
src/librustc_back/target/netbsd_base.rs
src/librustc_back/target/openbsd_base.rs
src/librustc_trans/back/link.rs
src/librustc_trans/back/linker.rs

index 5c4e01886a434366f9de5eb085b584aa26f9aec3..5a0ab83cd7231b8599fe6d4ca191d070a5198a2c 100644 (file)
@@ -19,6 +19,7 @@ pub fn opts() -> TargetOptions {
         linker_is_gnu: true,
         has_rpath: true,
         position_independent_executables: true,
+        full_relro: true,
 
         .. Default::default()
     }
index e44cd393289be3a23afdd0911c4b2e5e5c7dcb6f..ca116e82379b59a0be664ed53a63b07af0e0b6d7 100644 (file)
@@ -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()
     }
index e44cd393289be3a23afdd0911c4b2e5e5c7dcb6f..ca116e82379b59a0be664ed53a63b07af0e0b6d7 100644 (file)
@@ -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()
     }
index 8e7f463563c38e947d1775cde793d35cfac86aa1..c52b28708c36d8dd19a405632101c40da5041245 100644 (file)
@@ -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()
index 722d2fa16ef7a06a23689366bbf3af017cc0984f..e4e7f062f88f6fc4850882b167b81cb8be8bdd70 100644 (file)
@@ -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()
index edbbcf6f0b64701c3f1d33a219d61ba65e528170..673c01f4b7e7d838dcecdcbd71dfb94c7846fc2e 100644 (file)
@@ -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
@@ -454,6 +457,7 @@ fn default() -> 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(),
@@ -683,6 +687,7 @@ macro_rules! key {
         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);
@@ -870,6 +875,7 @@ macro_rules! target_option_val {
         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);
index 63245fcae767b34841a6cf9448b21c2518ef1a6c..1d7d1b36008aa78893e89b62d0b87280a2a350a0 100644 (file)
@@ -33,6 +33,7 @@ pub fn opts() -> TargetOptions {
         has_rpath: true,
         pre_link_args: args,
         position_independent_executables: true,
+        full_relro: true,
         .. Default::default()
     }
 }
index 051028d5c4a7752840887313af6e8fc6762c300e..df17f853b3b359d5f327528741abac7febcc2c83 100644 (file)
@@ -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()
     }
 }
index a4bbdef82f094bc9192fd66ba5c780273580a168..238b7fd2e19bc1be27829f1cac1c3cd6f09f8760 100644 (file)
@@ -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();
 
index 0b15886083a4e4d099613a43d86c06c88f86f74e..025b57956594a5291b068f7fb9d4e188d99f2a7b 100644 (file)
@@ -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);
@@ -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) {
@@ -428,6 +430,10 @@ fn position_independent_executable(&mut self) {
         // 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
@@ -595,6 +601,10 @@ fn position_independent_executable(&mut self) {
         // noop
     }
 
+    fn full_relro(&mut self) {
+        // noop
+    }
+
     fn args(&mut self, args: &[String]) {
         self.cmd.args(args);
     }