This issue discusses some limitations of the existing stack limit checks in wasmtime, independent from wasmfx.
Currently, wasmtime generates stack limit checks such that each function prelude includes a check that is equivalent to the following pseudo-code:
if $RSP < vmruntime_limits.stack_limit {
raise_trap(Trap.STACK_LIMIT_EXCEEDED)
}
Here, the stack_limit value in the VMRuntimeLimits is initialized whenever we enter wasm, to a value that is basically $RSP - _stacksize, where _stacksize is the corresponding wasmtime configuration/CLI option.
This shows that the existing stack limit checks are not designed to prevent stack overflows, as they don't prevent stack overflows in situations such as the following:
If we call into the host and re-enter wasm, the stack_limit in the VMRuntimeLimits gets re-initialized each time. Thus, if we perform enough nested (!) wasm->host->wasm calls, we may exhaust the underlying stack while always staying within the stack_limit.
The stack limit check takes no consideration for the space occupied by the function it is inserted into: It makes sure that the stack pointer does not exceed the limit at the start of the function, but it may exceed the limit during its subsequent execution.
This illustrates that the stack limit in wasmtime is currently intended not so much as a safety feature, but more like a resource limit: It ensures that you (roughly) stay within a certain amount of stack space, similar to the mechanism for tracking consumed "fuel". In order to reliably detect stack overflows, wasmtime relies on the existence of guard pages instead.
This shows that additional care is required if we want to re-purpose use the existing stack checks so that they do become the main safety check for preventing stack overflows.
This issue discusses some limitations of the existing stack limit checks in wasmtime, independent from wasmfx.
Currently, wasmtime generates stack limit checks such that each function prelude includes a check that is equivalent to the following pseudo-code:
Here, the
stack_limit
value in theVMRuntimeLimits
is initialized whenever we enter wasm, to a value that is basically$RSP
- _stacksize, where _stacksize is the corresponding wasmtime configuration/CLI option.This shows that the existing stack limit checks are not designed to prevent stack overflows, as they don't prevent stack overflows in situations such as the following:
stack_limit
in theVMRuntimeLimits
gets re-initialized each time. Thus, if we perform enough nested (!) wasm->host->wasm calls, we may exhaust the underlying stack while always staying within thestack_limit
.This illustrates that the stack limit in wasmtime is currently intended not so much as a safety feature, but more like a resource limit: It ensures that you (roughly) stay within a certain amount of stack space, similar to the mechanism for tracking consumed "fuel". In order to reliably detect stack overflows, wasmtime relies on the existence of guard pages instead.
This shows that additional care is required if we want to re-purpose use the existing stack checks so that they do become the main safety check for preventing stack overflows.