From cd24e155ea803e6ccbcfcfc7c6c6e47c928a696c Mon Sep 17 00:00:00 2001 From: xiaoyu Date: Thu, 22 May 2025 11:15:20 +0800 Subject: [PATCH] sess: stabilize relro-level Signed-off-by: xiaoyu --- compiler/rustc_codegen_ssa/src/back/link.rs | 2 +- compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_session/src/options.rs | 4 ++-- compiler/rustc_session/src/session.rs | 2 +- src/doc/rustc/src/codegen-options/index.md | 20 ++++++++++++++++++++ tests/run-make/relro-levels/Makefile | 8 ++++---- 6 files changed, 29 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index b603a878746..0d3ed50c3ec 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1972,7 +1972,7 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained: /// Add options making relocation sections in the produced ELF files read-only /// and suppressing lazy binding. fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) { - match sess.opts.unstable_opts.relro_level.unwrap_or(sess.target.relro_level) { + match sess.opts.cg.relro_level.unwrap_or(sess.target.relro_level) { RelroLevel::Full => cmd.full_relro(), RelroLevel::Partial => cmd.partial_relro(), RelroLevel::Off => cmd.no_relro(), diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 09141afd137..42a634372e9 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -627,6 +627,7 @@ macro_rules! tracked { tracked!(profile_generate, SwitchWithOptPath::Enabled(None)); tracked!(profile_use, Some(PathBuf::from("abc"))); tracked!(relocation_model, Some(RelocModel::Pic)); + tracked!(relro_level, Some(RelroLevel::Full)); tracked!(soft_float, true); tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); @@ -819,7 +820,6 @@ macro_rules! tracked { tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profiler_runtime, "abc".to_string()); tracked!(relax_elf_relocations, Some(true)); - tracked!(relro_level, Some(RelroLevel::Full)); tracked!(remap_cwd_prefix, Some(PathBuf::from("abc"))); tracked!(report_delayed_bugs, true); tracked!(sanitizer, SanitizerSet::ADDRESS); diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 7840a0ecf0b..7c0e1df7200 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1358,6 +1358,8 @@ pub(crate) fn parse_dump_solver_proof_tree( relocation_model: Option = (None, parse_relocation_model, [TRACKED], "control generation of position-independent code (PIC) \ (`rustc --print relocation-models` for details)"), + relro_level: Option = (None, parse_relro_level, [TRACKED], + "choose which RELRO level to use"), remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED], "output remarks for these optimization passes (space separated, or \"all\")"), rpath: bool = (false, parse_bool, [UNTRACKED], @@ -1703,8 +1705,6 @@ pub(crate) fn parse_dump_solver_proof_tree( "randomize the layout of types (default: no)"), relax_elf_relocations: Option = (None, parse_opt_bool, [TRACKED], "whether ELF relocations can be relaxed"), - relro_level: Option = (None, parse_relro_level, [TRACKED], - "choose which RELRO level to use"), remap_cwd_prefix: Option = (None, parse_opt_pathbuf, [TRACKED], "remap paths under the current working directory to this path prefix"), remark_dir: Option = (None, parse_opt_pathbuf, [UNTRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 5be122ffbde..3a0e4c804a4 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1017,7 +1017,7 @@ pub fn needs_plt(&self) -> bool { let dbg_opts = &self.opts.unstable_opts; - let relro_level = dbg_opts.relro_level.unwrap_or(self.target.relro_level); + let relro_level = self.opts.cg.relro_level.unwrap_or(self.target.relro_level); // Only enable this optimization by default if full relro is also enabled. // In this case, lazy binding was already unavailable, so nothing is lost. diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md index 8de638dde4f..582dad6bfcf 100644 --- a/src/doc/rustc/src/codegen-options/index.md +++ b/src/doc/rustc/src/codegen-options/index.md @@ -484,6 +484,26 @@ then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`, and the linker is instructed (`-static`) to produce a statically linked but not position-independent executable. +## relro-level + +This flag controls what level of RELRO (Relocation Read-Only) is enabled. RELRO is an exploit +mitigation which makes the Global Offset Table (GOT) read-only. + +Supported values for this option are: + +- `off`: Dynamically linked functions are resolved lazily and the GOT is writable. +- `partial`: Dynamically linked functions are resolved lazily and written into the Procedure + Linking Table (PLT) part of the GOT (`.got.plt`). The non-PLT part of the GOT (`.got`) is made + read-only and both are moved to prevent writing from buffer overflows. +- `full`: Dynamically linked functions are resolved at the start of program execution and the + Global Offset Table (`.got`/`.got.plt`) is populated eagerly and then made read-only. The GOT is + also moved to prevent writing from buffer overflows. Full RELRO uses more memory and increases + process startup time. + +This flag is ignored on platforms where RELRO is not supported (targets which do not use the ELF +binary format), such as Windows or macOS. Each rustc target has its own default for RELRO. rustc +enables Full RELRO by default on platforms where it is supported. + ## remark This flag lets you print remarks for optimization passes. diff --git a/tests/run-make/relro-levels/Makefile b/tests/run-make/relro-levels/Makefile index e0402f59f12..94f08bcb494 100644 --- a/tests/run-make/relro-levels/Makefile +++ b/tests/run-make/relro-levels/Makefile @@ -3,20 +3,20 @@ include ../tools.mk # only-linux # -# This tests the different -Zrelro-level values, and makes sure that they work properly. +# This tests the different -Crelro-level values, and makes sure that they work properly. all: # Ensure that binaries built with the full relro level links them with both # RELRO and BIND_NOW for doing eager symbol resolving. - $(RUSTC) -Zrelro-level=full hello.rs + $(RUSTC) -Crelro-level=full hello.rs readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO readelf -d $(TMPDIR)/hello | grep -q BIND_NOW - $(RUSTC) -Zrelro-level=partial hello.rs + $(RUSTC) -Crelro-level=partial hello.rs readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO # Ensure that we're *not* built with RELRO when setting it to off. We do # not want to check for BIND_NOW however, as the linker might have that # enabled by default. - $(RUSTC) -Zrelro-level=off hello.rs + $(RUSTC) -Crelro-level=off hello.rs ! readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO -- Gitee