Frontiers of Systems Programming

linear memory

When a Wasm module needs memory - to hold a string, an array, a data structure - where does that memory live, and why can't it accidentally scribble over the host? The answer is linear memory: a single, contiguous, byte-addressable array of bytes that belongs to the module and nothing else. The guest sees its memory as one flat block starting at offset 0, and every load and store is an index into that block.

Concretely, linear memory is just a big resizable byte array, sized in 64 KiB pages, that the runtime allocates outside the guest's reach and hands the module a window onto. A Wasm address is not a real machine pointer - it is an offset, a plain integer like 0x1040, into this one array. When the module does i32.load at offset 0x1040, the runtime checks that 0x1040 (and the four bytes after it) lie inside the current memory size; if they do, it reads; if they do not, it traps instead of touching anything else. The module can ask to grow its memory with memory.grow, and the host's own pointers, code, and other modules simply are not part of this array, so the guest has no name for them at all. This bounds-checking-by-construction is the whole trick: out-of-bounds inside the sandbox is a clean trap, never a read of host memory.

It matters because it is the concrete mechanism behind 'Wasm is sandboxed': isolation is not a promise bolted on afterward, it falls out of the fact that the guest can only address its own linear memory. But be precise about the limits. Wasm is memory-safe with respect to the host, not necessarily within the guest: a C program compiled to Wasm can still have a classic buffer overflow that corrupts its own linear memory and its own data structures - it just cannot escape into the host. So 'no memory-safety bugs' is false; 'no escape from the sandbox via memory' is the real, narrower guarantee.

i32.const 0x1040 ;; an address = a plain offset into THIS module's byte array i32.load ;; runtime checks 0x1040..0x1043 are in bounds, else it traps ;; the host's real memory has no address inside this array at all

A Wasm load is a bounds-checked index into the module's own byte array. Out of bounds traps; it can never reach host memory.

Linear memory protects the host from the guest, not the guest from itself. A buffer overflow inside Wasm corrupts the module's own linear memory exactly as it would natively; the guarantee is that this corruption stays inside the sandbox and cannot become a read or write of host memory.

Also called
Wasm linear memorythe Wasm heapWasm 記憶體