Soundness¶
The type system of WebAssembly is sound, implying both type safety and memory safety with respect to the WebAssembly semantics. For example:
All types declared and derived during validation are respected at run time; e.g., every local or global variable will only contain type-correct values, every instruction will only be applied to operands of the expected type, and every function invocation always evaluates to a result of the right type (if it does not trap or diverge).
No memory location will be read or written except those explicitly defined by the program, i.e., as a local, a global, an element in a table, or a location within a linear memory.
There is no undefined behavior, i.e., the execution rules cover all possible cases that can occur in a valid program, and the rules are mutually consistent.
Soundness also is instrumental in ensuring additional properties, most notably, encapsulation of function and module scopes: no locals can be accessed outside their own function and no module components can be accessed outside their own module unless they are explicitly exported or imported.
The typing rules defining WebAssembly validation only cover the static components of a WebAssembly program. In order to state and prove soundness precisely, the typing rules must be extended to the dynamic components of the abstract runtime, that is, the store, configurations, and administrative instructions. [1]
Results¶
Results can be classified by result types as follows.
Results ¶
For each value
in :The value
is valid with some value type .
Let
be the concatenation of all .Then the result is valid with result type
.
Results ¶
The result is valid with result type
, for any sequence of value types.
Store Validity¶
The following typing rules specify when a runtime store
To that end, each kind of instance is classified by a respective function, table, memory, or global type. Module instances are classified by module contexts, which are regular contexts repurposed as module types describing the index spaces defined by a module.
Store ¶
Each function instance
in must be valid with some function type .Each table instance
in must be valid with some table type .Each memory instance
in must be valid with some memory type .Each global instance
in must be valid with some global type .Each element instance
in must be valid with some reference type .Each data instance
in must be valid.Then the store is valid.
Function Instances ¶
The function type
must be valid.The module instance
must be valid with some context .Under context
, the function must be valid with function type .Then the function instance is valid with function type
.
Host Function Instances ¶
The function type
must be valid.Let
be the function type .For every valid store
extending and every sequence of values whose types coincide with :Then the function instance is valid with function type
.
Note
This rule states that, if appropriate pre-conditions about store and arguments are satisfied, then executing the host function must satisfy appropriate post-conditions about store and results. The post-conditions match the ones in the execution rule for invoking host functions.
Any store under which the function is invoked is assumed to be an extension of the current store. That way, the function itself is able to make sufficient assumptions about future stores.
Table Instances ¶
The table type
must be valid.The length of
must equal .For each reference
in the table’s elements :The reference
must be valid with reference type .
Then the table instance is valid with table type
.
Memory Instances ¶
The memory type
must be valid.The length of
must equal multiplied by the page size .Then the memory instance is valid with memory type
.
Global Instances ¶
The global type
must be valid.The value
must be valid with value type .Then the global instance is valid with global type
.
Element Instances ¶
For each reference
in the elements :The reference
must be valid with reference type .
Then the element instance is valid with reference type
.
Data Instances ¶
The data instance is valid.
Export Instances ¶
The external value
must be valid with some external type .Then the export instance is valid.
Module Instances ¶
Each function type
in must be valid.For each function address
in , the external value must be valid with some external type .For each table address
in , the external value must be valid with some external type .For each memory address
in , the external value must be valid with some external type .For each global address
in , the external value must be valid with some external type .For each element address
in , the element instance must be valid with some reference type .For each data address
in , the data instance must be valid.Each export instance
in must be valid.For each export instance
in , the name must be different from any other name occurring in .Let
be the concatenation of all in order.Let
be the concatenation of all in order.Let
be the concatenation of all in order.Let
be the concatenation of all in order.Let
be the concatenation of all in order.Let
be the length of .Then the module instance is valid with context
.
Configuration Validity¶
To relate the WebAssembly type system to its execution semantics, the typing rules for instructions must be extended to configurations
Configurations and threads are classified by their result type.
In addition to the store
Finally, frames are classified with frame contexts, which extend the module contexts of a frame’s associated module instance with the locals that the frame contains.
Configurations ¶
Under no allowed return type, the thread
must be valid with some result type .Then the configuration is valid with the result type
.
Threads ¶
Let
be the current allowed return type.Let
be the same context as , but with set to .Under context
, the instruction sequence must be valid with some type .Then the thread is valid with the result type
.
Frames ¶
The module instance
must be valid with some module context .Each value
in must be valid with some value type .Let
be the concatenation of all in order.Let
be the same context as , but with the value types prepended to the vector.Then the frame is valid with frame context
.
Administrative Instructions¶
Typing rules for administrative instructions are specified as follows.
In addition to the context
¶
The instruction is valid with type
, for any sequences of value types and .
¶
The instruction is valid with type
.
¶
The external function value
must be valid with external function type .Then the instruction is valid with type
.
¶
The external function value
must be valid with external function type .Then the instruction is valid with type
.
¶
The instruction sequence
must be valid with some type .Let
be the same context as , but with the result type prepended to the vector.Under context
, the instruction sequence must be valid with type .Then the compound instruction is valid with type
.
¶
Under the return type
, the thread must be valid with result type .Then the compound instruction is valid with type
.
Store Extension¶
Programs can mutate the store and its contained instances. Any such modification must respect certain invariants, such as not removing allocated instances or changing immutable definitions. While these invariants are inherent to the execution semantics of WebAssembly instructions and modules, host functions do not automatically adhere to them. Consequently, the required invariants must be stated as explicit constraints on the invocation of host functions. Soundness only holds when the embedder ensures these constraints.
The necessary constraints are codified by the notion of store extension:
a store state
Note
Extension does not imply that the new store is valid, which is defined separately above.
Store ¶
The length of
must not shrink.The length of
must not shrink.The length of
must not shrink.The length of
must not shrink.The length of
must not shrink.The length of
must not shrink.For each function instance
in the original , the new function instance must be an extension of the old.For each table instance
in the original , the new table instance must be an extension of the old.For each memory instance
in the original , the new memory instance must be an extension of the old.For each global instance
in the original , the new global instance must be an extension of the old.For each element instance
in the original , the new element instance must be an extension of the old.For each data instance
in the original , the new data instance must be an extension of the old.
Function Instance ¶
A function instance must remain unchanged.
Table Instance ¶
The table type
must remain unchanged.The length of
must not shrink.
Memory Instance ¶
The memory type
must remain unchanged.The length of
must not shrink.
Global Instance ¶
The global type
must remain unchanged.Let
be the structure of .If
is , then the value must remain unchanged.
Element Instance ¶
The vector
must either remain unchanged or shrink to length .
Data Instance ¶
The vector
must either remain unchanged or shrink to length .
Theorems¶
Given the definition of valid configurations, the standard soundness theorems hold. [2] [3]
Theorem (Preservation).
If a configuration
A terminal thread is one whose sequence of instructions is a result. A terminal configuration is a configuration whose thread is terminal.
Theorem (Progress).
If a configuration
From Preservation and Progress the soundness of the WebAssembly type system follows directly.
Corollary (Soundness).
If a configuration
In other words, every thread in a valid configuration either runs forever, traps, or terminates with a result that has the expected type. Consequently, given a valid store, no computation defined by instantiation or invocation of a valid module can “crash” or otherwise (mis)behave in ways not covered by the execution semantics given in this specification.