wasmfx / wasmfxtime

A fork of wasmtime (a fast and secure runtime for WebAssembly) supporting the WasmFX instruction set
https://wasmfx.dev/
Apache License 2.0
19 stars 1 forks source link

Limitations of wasmtime's existing stack limit checks #122

Open frank-emrich opened 8 months ago

frank-emrich commented 8 months ago

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:

  1. 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.
  2. 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.