-
Notifications
You must be signed in to change notification settings - Fork 202
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
Define __stack_base
and __stack_limit
globals in debug mode for stack overflow detection
#380
base: main
Are you sure you want to change the base?
Conversation
dbea8fa
to
fb46405
Compare
fb46405
to
a637299
Compare
…tack overflow detection That enables VMs to implement stack overflow detection or using passes like https://github.com/WebAssembly/binaryen/blob/main/src/passes/StackCheck.cpp
a637299
to
692afaf
Compare
I recognize that there are engines and tools implementing this already. But has there been any discussion of whether this is something we want to officially support in WASI contexts? An alternative would be to add code to LLVM to perform stack overflow checks when it bumps the stack pointer. That would have the advantage of keeping the stack pointer and the stack a toolchain implementation detail, rather than exposing them as a toolchain/engine convention. |
No, there wasn't any discussion other than WebAssembly/wasi-threads#12 I'm happy to discuss it more though either here or in the linked issue.
I don't think that's exclusive to proposed changes here? I'd assume the userspace code would have to somehow set stack boundaries (as it's the one that allocates memory for the stack) so LLVM can generate the code for stack overflow check (e.g. we could possibly integrate the pass from binaryen to LLVM). In that case, LLVM would have to define those globals, so we remove definitions of Or did you have something completely different in mind? |
|
Yeah, that was the option I suggested WebAssembly/wasi-threads#12 but I didn't really like it so I asked others for opinion. The reason I'm not sure if making them arguments of My use of stack overrun check is only in debug mode, but I guess others might use it in production code as well; another option would be to always check if globals |
is WASI the right forum for this topic? |
Your top post here says that VMs may implement the stack check. That suggests that you're proposing a change to the module-engine ABI. Is that the plan here? If so, then I have the concern that this is adding things previously considered implementation details to the module-engine ABI, and I'd like to suggest doing the checking in LLVM or other tools instead. If you're proposing that this is just part of the C ABI, and the LLVM or binaryen or other tools will insert the checking code into the wasm module, then this is just part of the C ABI, and it looks reasonable to me. Doing the checking in the wasm module does increase code size, which I care about, so a possible way to optimize this would be to explore adding a feature to the core wasm spec to define value-range predicates for globals, looking something like this: (global $sp.base (mut i32) (i32.const 0))
(global $sp (mut i32) (i32.const 0) (i32.ge_u (global.get $sp.base) (global.get $sp))
(global $sp.limit (mut i32) (i32.const 0) (i32.ge_u (global.get $sp) (global.get $sp.limit)) Like global inits, there'd be rules about what form the expression can have. Just a simple |
Interesting idea! I wonder if there are any other uses for these kind of bounds checks? I wonder if the engine could make this fast enough to warrant enabling these check in release build too? Presumably they won't come at zero cost. Thus far (at least in emscripten) detecting shadow stack overflow has been something we only recommend in debug builds. Normally in debug builds folks tend to care less about that extra size (and performance) costs of the checks. Even if we do go for a core wasm proposal to make this more efficient, there are good reasons to want to use the user-space / in-module checks until that becomes available. It makes sense to me that the in-module checks should be part of the C ABI / tooling conventions. |
WAMR has a heuristic to detect C ABI and perform the stack overflow/underflow checks. (it isn't new.) |
Hi,
No, my plan was to extend the C ABI (I'll update the relevant documents in the tooling convention's repo once we agree on the approach here). I mentioned VMs because this is what WAMR currently does for single-threaded applications (as @yamt said, it has ways to figure out the stack pointer, so it could potentially also read the stack boundaries in multi-threaded app, at least until the tooling is ready).
That's interesting idea. I'll think about it and might discuss that with others. Do you think that's a blocker though for proceeding with extending C ABI? I personally only need that feature in debug mode, however, once this becomes part the C ABI, I guess we'll have to enable it for release builds as well (unless we specify in the doc that it's an optional feature). |
No, I don't think it's a blocker. Since this is about the C ABI, it's not specific to WASI, so addressing @yamt's question above, I think that means the place to propose this is the C ABI, or possibly a new document in the tool-conventions repository. |
That enables VMs to implement stack overflow detection or using passes like https://github.com/WebAssembly/binaryen/blob/main/src/passes/StackCheck.cpp
See WebAssembly/wasi-threads#12