-
Notifications
You must be signed in to change notification settings - Fork 8
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
Should runtimes have access to thread's stack boundaries? #12
Comments
In emscripten we have found it useful to be able to do bounds checking in userspace. For that, we use binaryen pass which we run over the compiled module: https://github.com/WebAssembly/binaryen/blob/main/src/passes/StackCheck.cpp. This adds instrumentation to any Doing it this way means we don't depend on any features of the runtime (for example, v8 doesn't need to be aware of the shadow stack at all). To make this work with threads does require the setting of the stack start/end globals during the startup of each thread, but this is something that perhaps wasi-libc can do in debug/checked mode? |
Wasm indeed doesn't currently have read-only memory segments. There's the beginning of a proposal, but it's early. |
i don't think it's necessary for this particular case. if enough info about the stack and associated "guard page" is provided to |
IIUC that would no longer be conforming to the wasm spec. For example, its perfectly valid in wasm to write a function like |
sure. but it's what exactly we want to detect, isn't it? in that case, i guess the only way "conforming" to the current spec is to insert explicit checks at C compiler level.
i agree it's unfortunate. but wasm is not the only environment having something at address 0. |
WAMR performs boundary checks by intercepting |
Yes, and I think this check will have to be disabled for spawned threads. I think the extra pass shared by @sbc100 seems like reasonable approach; @sbc100, do you think that's something we could integrate to LLVM and control through a compiler's command line argument? |
Right now its part of wasm-opt (binaryen), which only has basic integration with clang today. So you would need to run |
@sbc100 thanks, I think that's enough for now. I wonder though if there's any plan to integrate it to LLVM in a (near) future? |
There have be times when we have discussed deeper integration of binaryen with llvm, but I don't know of any immediate plans. |
Another option in the space of more Binaryen integration into LLVM could be a WASI port of Binaryen which would hopefully be very simple to use in relevant toolchains (just a wasm binary). |
to me it seems simpler to tweak the api to provide the stack boundary info to
maybe |
The Each new thread would need to somehow call this function as one of the very first thing is does. In emscripten we currently call this function from JS before we call the thread entry point, but perhaps we can figure out a way for new threads to call this function before doing anything else. |
At the moment runtimes can access stack boundaries reading by reading
__heap_base
/__data_end
(or__stack_high
/__stack_low
) globals (if they're exported). That works for the main thread, but won't work for the threads we spawn with the newwasi_thread_spawn
API.Having access to stack boundaries and the stack pointer (which is also not straightforward to retrieve, but possible) would allow runtimes to detect stack overflow or underflow. However, that would slightly complicate the API (we'd probably have to add another parameter to
wasi_thread_spawn
).I personally see a lot of value in having stack overrun (mainly overflow, but underflow can happen too) protection in VMs, but at the same time I'm in favor of having the API simple, at least for now.
I'd like to know others' opinion and see if I didn't miss anything obvious here.
Just a note here - POSIX's pthread_create allows to have a guard memory which prevents from stack overflow, but I don't think this is going to work on WASM as it's not possible to specify read-only memory segments (or is it?).
The text was updated successfully, but these errors were encountered: