-
Notifications
You must be signed in to change notification settings - Fork 13.2k
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
Remove morestack support #27338
Remove morestack support #27338
Conversation
🎊 amaze! |
I'm also a bit wary that this makes it much harder for anybody to add true split stacks back to a custom build of Rust (since it removes everything), but maybe it's time to let that dream die. |
I feel like our story has been worn down here quite a bit over time, so I don't personally feel that our usage of morestack is really gaining us much memory safety today. One of our tier 1 platforms, Windows, hasn't been using morestack for months now, but I also wouldn't consider ourselves memory unsafe on Windows. |
morestack is irrelevant on Windows because stack probes are already implemented there. That isn't a very strong argument for allowing arbitrary wild memory accesses on Linux. |
Amen to that 👍. |
Eh, the danger on Linux is fairly small, you need the following conditions for it to actually cause problems:
That's quite a significant amount of requirements, to the point that hitting all of them almost certainly requires doing so deliberately. Obviously having stack probes is better than not, but I'm not going to be kept awake by the removal of morestack. |
how about also adding a lint that checks the stack size of functions? It would create some false positives since optimizations might lower the stack usage, but I don't think that's too important. |
let guard = thread_info::stack_guard().unwrap_or(0); | ||
let addr = (*info).si_addr as usize; | ||
|
||
let _ = ::sys::stdio::Stderr::new().and_then(|mut s| { | ||
use io::Write; | ||
s.write_fmt(format_args!("{:?} {:?} {:?}", guard, addr, PAGE_SIZE)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
left-over debug print?
Given morestack doesn’t work on non-linux/non-apple anyway, and all of the platforms have ASLR I’m not convinced “hole” is that much bigger than it was before. Sure, it exists, but to exploit it you pretty much have to be doing it maliciously, and for malicious purposes there’s many much much easier ways to do that via So overall 👍 from me. |
_data: *mut libc::c_void) { | ||
|
||
// We can not return from a SIGSEGV or SIGBUS signal. | ||
// See: https://www.gnu.org/software/libc/manual/html_node/Handler-Returns.html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't remove this comment. Add one stating why we can return on linux, macos, bitrig, netbsd and openbsd. (Should probably be tested on all those platforms as well)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And FreeBSD. I think we're good on all the UNIXes that Rust currently supports; if not, the re-raise code needs to be kept. (I ran out of motivation to go categorize this and send in a PR for #26458 but I could go do that now I guess.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, I forgot that I meant to reword this, and I've now done so.
I think that's okay, given that other languages (Go) that used segmented stacks have had to move away from them anyway. |
4b975bb
to
50e51f5
Compare
Big 👍 to both the idea and the code. The continued existence of That said, I do agree with the wariness about removing this from Linux while stack probes aren't present. (I'm still not totally sure what's the blocker, as in why MIPS can't use generic stack probing, but let's have that conversation on #16012.) I am concerned about whether this makes it easy to write "safe" code (that is, code that doesn't use That said, if there's already a way for malicious code to deliberately violate memory safety without I don't think custom split stacks are a compelling reason to keep this code around; I agree this is the right long-term thing to do. |
@@ -94,7 +94,6 @@ pub fn opts(arch: Arch) -> TargetOptions { | |||
// | |||
// SS might be also enabled on Arm64 as it has builtin support in LLVM | |||
// but I haven't tested it through yet | |||
morestack: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comments above this line are now irrelevant.
Sorry, I didn’t mean to imply there’s already a way to access arbitrary memory using only safe code. What I’m trying to say that you have to be deliberately trying to write malicious safe code to reasonably expect to exploit lack of Sure, that is not good enough for safety Rust-without-unsafe tries to guarantee, but since we expect to implement stack probes for all platforms sometime in the future anyway… |
cae8577
to
ce2b8d1
Compare
And to clarify, we don't currently use stack probes anywhere today. From what I understand it sounds like LLVM has support for stack probes on Windows but not on other platforms just yet. That being said I believe there's more detailed discussion over at #16012 |
ce2b8d1
to
aaa1bba
Compare
⌛ Testing commit 143ca53 with merge b18b3bf... |
@bors: r- force Travis failed in what looks like a pretty legit fashion. |
⛄ The build was interrupted to prioritize another pull request. |
143ca53
to
acb8961
Compare
term(signum); | ||
// If the faulting address is within the guard page, then we print a | ||
// message saying so. | ||
if guard != 0 && guard - PAGE_SIZE <= addr && addr <= guard { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be addr < guard
.
acb8961
to
acbdf0a
Compare
@bors: r+ acbdf0a1bded880011cfff5f487066a8d16f2e0b |
⌛ Testing commit acbdf0a with merge aa3d701... |
💔 Test failed - auto-win-gnu-32-opt |
acbdf0a
to
fef6937
Compare
This commit removes all morestack support from the compiler which entails: * Segmented stacks are no longer emitted in codegen. * We no longer build or distribute libmorestack.a * The `stack_exhausted` lang item is no longer required The only current use of the segmented stack support in LLVM is to detect stack overflow. This is no longer really required, however, because we already have guard pages for all threads and registered signal handlers watching for a segfault on those pages (to print out a stack overflow message). Additionally, major platforms (aka Windows) already don't use morestack. This means that Rust is by default less likely to catch stack overflows because if a function takes up more than one page of stack space it won't hit the guard page. This is what the purpose of morestack was (to catch this case), but it's better served with stack probes which have more cross platform support and no runtime support necessary. Until LLVM supports this for all platform it looks like morestack isn't really buying us much. cc rust-lang#16012 (still need stack probes) Closes rust-lang#26458 (a drive-by fix to help diagnostics on stack overflow)
fef6937
to
7a3fdfb
Compare
This commit removes all morestack support from the compiler which entails: * Segmented stacks are no longer emitted in codegen. * We no longer build or distribute libmorestack.a * The `stack_exhausted` lang item is no longer required The only current use of the segmented stack support in LLVM is to detect stack overflow. This is no longer really required, however, because we already have guard pages for all threads and registered signal handlers watching for a segfault on those pages (to print out a stack overflow message). Additionally, major platforms (aka Windows) already don't use morestack. This means that Rust is by default less likely to catch stack overflows because if a function takes up more than one page of stack space it won't hit the guard page. This is what the purpose of morestack was (to catch this case), but it's better served with stack probes which have more cross platform support and no runtime support necessary. Until LLVM supports this for all platform it looks like morestack isn't really buying us much. cc #16012 (still need stack probes) Closes #26458 (a drive-by fix to help diagnostics on stack overflow) r? @brson
On the functionality side, morestack is gone (rust-lang/rust#27338), and rustrt_native is gone (rust-lang/rust#27176). On the implementation side, connect has been renamed to join (rust-lang/rust#26957).
The Rust version is now at: ``` rustc 1.9.0-nightly (0dcc413e4 2016-03-22) ``` This includes a fix for the following build error that the new version produced: ``` src/rust_base.rs:17:1: 19:2 error: definition of an unknown language item: `stack_exhausted`. [E0522] src/rust_base.rs:17 pub extern fn stack_exhausted() { src/rust_base.rs:18 panic!("Stack exhausted"); src/rust_base.rs:19 } src/rust_base.rs:17:1: 19:2 help: run `rustc --explain E0522` to see a detailed explanation ``` It looks like the `stack_exhausted item was removed last year: rust-lang/rust#27338 This didn't cause an error so far, because the compiler didn't complain about defining lang items that don't exist. This seems to have changed in this pull request: rust-lang/rust#32264
The `stack_exhausted` lang item was removed in rust-lang/rust#27338. Therefore, our (empty) implementation of `stack_exhausted` can be removed.
This commit removes all morestack support from the compiler which entails:
stack_exhausted
lang item is no longer requiredThe only current use of the segmented stack support in LLVM is to detect stack
overflow. This is no longer really required, however, because we already have
guard pages for all threads and registered signal handlers watching for a
segfault on those pages (to print out a stack overflow message). Additionally,
major platforms (aka Windows) already don't use morestack.
This means that Rust is by default less likely to catch stack overflows because
if a function takes up more than one page of stack space it won't hit the guard
page. This is what the purpose of morestack was (to catch this case), but it's
better served with stack probes which have more cross platform support and no
runtime support necessary. Until LLVM supports this for all platform it looks
like morestack isn't really buying us much.
cc #16012 (still need stack probes)
Closes #26458 (a drive-by fix to help diagnostics on stack overflow)
r? @brson