-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Extend stack probe support to non-tier-1 platforms, and clarify policy for mitigating LLVM-dependent unsafety #43241
Comments
All of them. LLVM only currently has support for x86. |
GCC has |
@cuviper Would it suffice to give the user the ability to enforce that no given function ever exceeds the size of the guard page? Maybe I'm naive, but I'm assuming that our guard page support is platform-independent, and that we can calculate the maximum size of any given monomorphized function (I can't think of a reason why we couldn't given that we don't support alloca). |
Page size is not a static value on some arches, although for this purpose you could probably get away with just assuming a minimum 4KB. Stack probing on those arches will probably have to use 4KB strides as a worst case, even when the real page size is 64KB/etc., unless we want those to query sysconf at runtime. Also, as we learned in #43052, the Linux kernel now implements a much larger effective guard size, but we have no way to detect that at runtime, unless you tried to probe a fault on purpose. Anyway, 4KB seems to me like a pretty low stack-frame threshold for userspace programs. I guess some users might be happy with that, but I think a tunable threshold would be more useful. |
There's also different behavior between the main thread's growable stack and the fixed stack space of other threads. See |
I suppose another difficulty is that LLVM can inline functions as it pleases, which would poke a hole in any attempt to statically lint against large functions in the frontend. |
This is not realistic given the way LLVM is designed. You'd have to plug your pass very late into the MI pipeline, which by itself will need target-specific LLVM patches (that are quite a bit more complex than stack probes themselves). |
triage: P-medium |
Well, gnux32 (Tier 2) is x86_64, with 32-bit pointers, and theory has support. |
Revisiting: this statement is wrong. There is a way to ask LLVM to emit this information because it gained exactly such a pass plugged very late into MC pipeline. See this. |
Right now we implement X86 probes with a call to compiler-builtins' That's also X86-only so far, but this should be the path forward for other targets. |
Use probe-stack=inline-asm in LLVM 11+ Fixes (?) rust-lang#74405, related to rust-lang#43241 r? `@cuviper`
Does #77885 mean that stack probes are now enabled on all LLVM targets? If so, should this be closed? |
Not yet -- I would like to test additional architectures natively before enabling them, because we did uncover bugs in X86 codegen. Also, PowerPC and SystemZ (s390x) are the only other targets that have implemented stack probes at all. |
Enable inline stack probes on PowerPC and SystemZ The LLVM PowerPC and SystemZ targets have both supported `"probe-stack"="inline-asm"` for longer than our current minimum LLVM 13 requirement, so we can turn this on for all `powerpc`, `powerpc64`, `powerpc64le`, and `s390x` targets in Rust. These are all tier-2 or lower, so CI does not run their tests, but I have confirmed that their `linux-gnu` variants do pass on RHEL. cc rust-lang#43241
Enable inline stack probes on PowerPC and SystemZ The LLVM PowerPC and SystemZ targets have both supported `"probe-stack"="inline-asm"` for longer than our current minimum LLVM 13 requirement, so we can turn this on for all `powerpc`, `powerpc64`, `powerpc64le`, and `s390x` targets in Rust. These are all tier-2 or lower, so CI does not run their tests, but I have confirmed that their `linux-gnu` variants do pass on RHEL. cc rust-lang#43241
As of LLVM 18, |
As of #42816 , all (current) tier-1 platforms are protected against the potential memory unsafety demonstrated in #16012 . However, this protection is dependent upon platform-dependent LLVM support, so AFAIK most of our supported tier-2 and tier-3 platforms ( https://forge.rust-lang.org/platform-support.html ) are still theoretically unprotected.
Proper resolution of this issue will depend on extending LLVM's stack probe support for various platforms, (which should be done regardless of the discussion in the next paragraph). See https://reviews.llvm.org/D34387 for pcwalton's original x86 implementation, https://reviews.llvm.org/D34386 for the implementation of the attribute itself, and #42816 for the work needed on rustc's side.
But here's the more important concern: the list of potential platforms is unbounded, and we need to decide where to draw the line. As minor as the safety hole may be, is it an abrogation of Rust's claim to guarantee memory safety if that safety is only enforced on "popular" platforms? If so, is it worth considering some sort of blanket check that can be implemented in the frontend for use only on platforms where stack probes are unimplemented? For instance, given that we statically know the stack size of all types, could we perhaps enforce an upper bound on the size of a type (perhaps only in debug mode)? I think this discussion may be relevant to #10184 as well.
The text was updated successfully, but these errors were encountered: