Hi!
I've been looking into wasmtime / wasm and am very very new to wasmtime / wasm. I'm just wondering if people could clear up some confusion I have regarding two things.
1) I've been looking all over and can't seem to find a definitive answer on this, but where is dynamic memory located? Is it put in the module's linear memory space or somewhere else in limbo? Also does linear memory use guard pages or bounds checking (I guess this is a question of how large dynamic memory can actually become?
2) What are the spectre defenses deployed on x86 - specifically on bounds checking (dynamic memory)? It seems to be a cmov
instruction? And is this done for every load that occurs?
Thanks!
Typo on 1) should be "Also does dynamic memory use guard pages or bounds checking (I guess this is a question of how large dynamic memory can actually become?)"
where is dynamic memory located?
One question first: what do you mean by "dynamic memory"? There are at least two plausible interpretations in Wasmtime lexicon -- memory allocated by malloc
in a Wasm guest, or a particular implementation style of a Wasm linear memory (with dynamic checks).
I'll take "dynamic memory" to mean "memory allocated by malloc
"; if so, e.g. in a C program compiled to WASI, then yes, dynamic memory allocations are allocated in linear memory. The C (or Rust or ...) notion of "one large address space" with pointers is mapped to Wasm linear memory 0, typically, and a malloc implementation is linked into the Wasm module.
Also does linear memory use guard pages or bounds checking
Both or one or the other, depending on configuration! This file implements the Wasm-to-IR translation that includes the necessary checks, and describes all the cases. For performance typically we want to use guard pages (which implies a 4GiB + guard virtual-memory region, for 32-bit wasm pointers) so we don't have the overhead of explicit bounds-checks.
We generally call a memory sized and configured such that no dynamic bounds-checks are required a "static memory", and a memory where runtime checks are required a "dynamic memory", though semantically they are both exactly the same thing (a linear memory) from the Wasm guest's point of view. Both can grow in size; in the "static" case this involves page permissions (updating the guard region).
What are the spectre defenses deployed on x86
We use a cmov
to shunt the pointer to null on the misspeculated path of any bounds-checks, yes. For guard page-based ("static") memories, there is no need for that because even a misspeculated 32-bit offset will always land in the guard.
There are some more details here including what we do for a few other instructions (e.g., indirect branches). You'll probably want to read that whole file actually as it describes our security posture and techniques in a lot of depth.
Thanks for you response!
For dynamic memory I think both interpretations are of interest to me, but your response clears up any confusion that I had.
Thanks again!
Alan Wang has marked this topic as resolved.
Last updated: Dec 23 2024 at 12:05 UTC