sess: stabilize -Zrelro-level
as -Crelro-level
by davidtwco · Pull Request #121694 · rust-lang/rust (original) (raw)
Stabilization report
RELRO (_Rel_ocation _R_ead-_O_nly) is a binary hardening technique, it makes the Global Offset Table (GOT) read-only (preventing some avenues of exploitation).
Roughly speaking, calls to functions from dynamic libraries are implemented using the Global Offset Table (GOT) and Procedure Linking Table (PLT) in an ELF file. A call to foo
from a foreign library is codegen'd to a call into a stub in the PLT, foo@plt
, which looks up the GOT for the real address of foo
. If this is the first time that foo
has been called, then that won't be known, and the fallback stub's address will be in the GOT and that will be jumped to instead. The fallback handler calls into ld.so
to resolve the function and then writes its address into the GOT. Subsequent calls to foo@plt
will just jump straight to foo
.
This scheme necessitates that the GOT is writable, which opens up the possibility for exploitation. Full RELRO resolves all the function addresses when the program is initially loaded and populates the GOT eagerly - this uses more memory and increases process startup time - but it allows the GOT to be made read-only (both .got
and .got.plt
). Partial RELRO only makes the non-PLT part of the GOT read-only (.got
), but .got.plt
is still writable. Both partial and full RELRO re-order sections to protect them from being written by buffer overflows.
rustc allows configuration of RELRO levels with -Zrelro-level={off,partial,full}
and if this isn't set, then each target can set a default RELRO level. We enable full RELRO on many of our targets by default (e.g. Linux, BSD, etc).
This feature has been implemented since 2017 and has been enabled by default for most platforms on which it is enabled since that initial implementation.
If we don't enable RELRO by default on a target, then users have no way of requesting it on stable toolchains. If RELRO is undesirable, then users have no way of disabling it on stable toolchains.
As per other platform-specific codegen flags, this option is ignored on those targets (e.g. like -Ccontrol-flow-guard
on non-Windows targets).
Tests
History
- Add support for full RELRO #43170 (initial implementation)
- Add relro-level tests #48388 (bug fix + test)
Unresolved questions
- None!