-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Consider applying -Wl,-z,relro
or -Wl,-z,relro,-z,now
by default
#29877
Comments
Sounds cool, but I didn't ask for that, @brson :) Cheers, |
Oops, wrong @gus. Sorry! Strong beard though. |
;) On Mon, Nov 16, 2015, 20:55 Brian Anderson notifications@github.com wrote:
|
There is something similiar on Fedora: Change: Harden all packages |
Downside is that not every alternative linker out there might support the flags. |
@alexcrichton do recall if we've done anything here? I don't see 'relro' in the source. |
No I don't believe we ever implemented this, but would be good to do so! |
er didn't mean to close |
FWIW, I also apply |
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 <johannes@kyriasis.com>
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 #29877. --- I'm not entirely certain if this is the best way to do it, but I figured mimicking the way it's done for PIE seemed like a good start at least. I'm not sure whether we want to have it enabled by default globally and then disabling it explicitly for targets that don't support it though. I'm also not sure whether the `full_relro` function should call `bug!()` or something like it for linkers that don't support it rather than no-opping.
Why not build with |
Using a GOT instead will cause every function call to require a load of the address, even if the target is guaranteed to resolve in the same DSO. When emitting relocations for a PLT, the linker can replace PLT calls with direct relative calls in case of non-exported symbols AFAIK which is almost all calls in an average Rust program. |
@bjorn3 I think PLT relocations must resolve to GOT slots anyway. |
A PLT relocation for an external symbol is implemented as pc-relative call to a stub function which loads from the GOT. For an internal symbol this can trivially be relaxed to a pc-relative call to the actual function. The stub function is generated by the linker, not the compiler, so the linker has full control over it. For a GOT relocation however the load is part of the code emitted by the compiler and can't be replaced. |
@bjorn3 internal symbols with "default" visibility are still interposable, and the compiler/linker are forced* to place a GOT entry for them - to account for the case that another binary preempts them. *clang sometimes optimizes these calls anyway, but in doing so it knowingly breaks the ABI. |
Rust uses |
@bjorn3 This is an empirical matter. This toy test:
Seems to show that with or without PLT, in both gcc and clang, the GOT is used. Am I missing something? |
Actually this switch just avoids the interposition infrastructure for calls into the same translation unit.
Indeed, the GOT is redundant for rust - and largely for C++ too. Yet this is not the point in question: The point is that PLT is redundant. The PLT isn't there to facilitate interposition, it is there to facilitate lazy binding. And this merge shows that rust (rightfully) avoids lazy binding anyway, so why pay the extra overhead?
You're right, internal symbols have hidden visibility and cannot be interposed. Again, this is a side discussion and not the point of my comment. |
We don't yet know when compiling object files if non-local rust symbols will be looked up inside the same DSO or outside. Only once we start linking do we know this. This rules out using non-PLT PC-relative relocations for position independent executables. So PLT or GOT relocations are the only option. GOT relocations can't be relaxed to regular PC-relative calls, so PLT relocations it is. |
These are some options that Debian applies, and that @gus wants to apply to all Rust code. Generally, Rust likes to harden things by default when there are no obvious disadvantages. Is it feasible that we might just use these by default?
The text was updated successfully, but these errors were encountered: