Apr 10, 2026·7 min read·2 visits
A logic error in Cranelift's ISLE rules on AArch64 causes memory access miscompilation when Spectre mitigations are disabled. This results in divergent bounds checking and memory loading, enabling out-of-bounds memory access and sandbox escapes.
A miscompilation vulnerability in the Wasmtime Cranelift compilation backend for AArch64 allows an attacker to achieve an out-of-bounds read and write, leading to a complete sandbox escape.
A critical logic flaw in the Wasmtime Cranelift compilation backend affects the AArch64 instruction selection language (ISLE) rules. This flaw manifests as a miscompilation bug under specific configuration conditions. The resulting machine code introduces a severe memory corruption vulnerability within the WebAssembly sandbox.
The vulnerability strictly resides within the AArch64 code generation path of Cranelift, specifically handling memory access optimization patterns. It is limited to environments executing on ARM64 processors. Other architectures, such as x86_64, process these compilation rules using entirely different ISLE logic and remain unaffected by this specific flaw.
Attackers interacting with a vulnerable Wasmtime runtime can supply crafted WebAssembly modules to exploit this compilation divergence. Successful exploitation yields out-of-bounds read (CWE-125) and out-of-bounds write (CWE-787) primitives against the host memory space. This directly leads to a sandbox escape, allowing unauthenticated remote code execution on the underlying host environment.
Cranelift attempts to optimize WebAssembly memory accesses by folding constant shift operations into the native scaled register addressing mode of the AArch64 hardware. The instruction selection rules evaluate access patterns structured as load(iadd(base, ishl(index, amt))). When a match occurs, Cranelift emits a hardware-level shift instruction formatted as LDR [Xn, Xm, LSL #amount].
The logic error occurs in rules 6 and 7 of cranelift/codegen/src/isa/aarch64/inst.isle when validating the shift amount. To ensure the constant shift amt is safe to fold, the compiler applies a mask to the immediate value. The compiler erroneously used the data type of the loaded value (ty) to calculate this mask instead of the type of the index operand being shifted (shift_ty).
Consider a guest WebAssembly module performing an i8 load where an i64 index is shifted by 56 bits. The vulnerable ISLE rule calculates the mask as 56 & (bit_width(i8) - 1), which evaluates to 56 & 7 = 0. Because 1 << 0 equals the 1-byte size of the i8 type, the rule incorrectly determines that a zero-bit shift is required for the optimization.
The rule matches successfully despite the invalid calculation constraint. Cranelift proceeds to emit an AArch64 machine instruction with a scale of 0 instead of the required 56-bit shift. This compilation error creates a critical divergence between the bounds checking logic and the actual memory access instruction.
The compilation discrepancy stems directly from the ISLE lowering rules defining register scaling. The vulnerable implementation failed to capture the type of the shifted value, relying entirely on the target memory operation type. The code diff below demonstrates the flawed instruction matching definition before the security patch was applied.
-(rule 6 (amode_no_more_iconst ty (iadd x (ishl y (iconst (u64_from_imm64 n)))) offset)
- (if-let true (u64_eq (ty_bytes ty) (u64_wrapping_shl 1 (shift_masked_imm ty n))))
+(rule 6 (amode_no_more_iconst ty (iadd x (ishl y @ (value_type shift_ty) (iconst (u64_from_imm64 n)))) offset)
+ (if-let true (u64_eq (ty_bytes ty) (u64_wrapping_shl 1 (shift_masked_imm shift_ty n))))
(amode_reg_scaled (amode_add x offset) y))The patch introduces the @ (value_type shift_ty) binding syntax into the ISLE matching rule. This binding explicitly captures the data type of the index operand y being shifted into the variable shift_ty. The subsequent condition then uses shift_masked_imm shift_ty n instead of shift_masked_imm ty n to determine the bitmask.
This type correction ensures the compiler applies the bitmask corresponding to the actual 64-bit operand rather than the 8-bit load target. The bounds check logic and the memory access emission logic are subsequently realigned, preventing the divergent compilation path. The fix comprehensively resolves the vulnerability within these specific optimization rules by removing the miscalculation vector.
Exploitation requires a specific sequence of actions and strict runtime preconditions to function correctly. The vulnerability only triggers when executing 64-bit WebAssembly linear memories or when the Wasmtime environment has Config::wasm_memory64 explicitly enabled. Additionally, the target environment must run with Spectre mitigations and signals-based-traps explicitly disabled.
> [!NOTE] > Exploitation relies heavily on non-default configuration states, specifically the deliberate disabling of Spectre mitigations within the Wasmtime runtime. Default configurations generate a more conservative code shape that avoids this specific ISLE optimization entirely.
An attacker compiles a WebAssembly module containing the load(iadd(base, ishl(index, amt))) pattern. The attacker provides an index designed to overflow the 64-bit address space when shifted by the intended amount during bounds checking. The explicit bounds check applies the correct 56-bit shift, causing the address to wrap around to a value that safely passes the memory constraint validation.
During execution, the actual load instruction applies the 0-bit shift generated by the miscompiled ISLE rule. The bounds check passes based on the wrapped high address, but the memory operation uses the unshifted, low address value. This execution discrepancy allows the attacker to read or write directly to memory locations outside the allocated WebAssembly linear memory.
The primary consequence of this vulnerability is a complete WebAssembly sandbox escape. An attacker gains precise, arbitrary memory read and write capabilities across the host application's address space. This access level critically compromises the foundational isolation guarantees provided by the Wasmtime runtime.
Attackers can leverage the out-of-bounds write primitive to overwrite function pointers, execution contexts, or sensitive configuration data within the host process. The out-of-bounds read primitive allows the extraction of cryptographic material, session tokens, or internal operational states. These primitives combine to facilitate unauthenticated remote code execution directly on the underlying AArch64 host hardware.
The vulnerability requires high complexity due to the narrow configuration prerequisites. Environments with default settings remain largely protected because Cranelift skips the vulnerable optimization rule. Consequently, the CVSS v4.0 vector correctly weights the specific attack complexity requirements (AT:P).
Despite the constraints, the severity remains critical at 9.0 due to the profound impact metrics across the vulnerability domain (VC:H/VI:H/VA:H/SC:H/SI:H/SA:H). Any environment explicitly disabling Spectre mitigations on AArch64 hardware for performance gains is exposed. The impact strictly extends beyond the vulnerable Wasmtime process to the entire host system relying on the sandboxed execution boundary.
The authoritative resolution requires updating the Wasmtime runtime to a fully patched version. The maintainers have backported the ISLE rule fix to multiple stable release lines. Administrators must deploy Wasmtime versions 36.0.7, 42.0.2, or 43.0.1 depending on their current integration branch.
If patching is not immediately feasible, operators must alter the Wasmtime runtime configuration to prevent exploitation. Enabling Spectre mitigations serves as a complete workaround. When Spectre mitigations are active, the Cranelift compiler bypasses the vulnerable ISLE optimization rules entirely, neutralizing the compilation divergence.
A secondary configuration workaround involves explicitly disabling 64-bit memory support. Administrators can verify that Config::wasm_memory64 is disabled across all deployment environments. This restricts the addressing space and prevents the conditions required to trigger the divergent bounds check logic during the instruction folding phase.
Security operations teams should implement configuration audits specifically targeting AArch64 hardware fleets running Wasmtime payloads. The audit must identify instances where Spectre mitigations or signals-based-traps have been turned off. Detection of active exploitation is complex, as the attack payload exists within validly formatted WebAssembly binaries without requiring external network anomalies.
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Wasmtime Bytecode Alliance | >= 32.0.0, < 36.0.7 | 36.0.7 |
Wasmtime Bytecode Alliance | >= 37.0.0, < 42.0.2 | 42.0.2 |
Wasmtime Bytecode Alliance | 43.0.0 | 43.0.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-125, CWE-787 |
| Attack Vector | Network / Arbitrary WebAssembly Module |
| CVSS v4.0 | 9.0 |
| Impact | Sandbox Escape / Remote Code Execution |
| Architecture | AArch64 (ARM64) |
| Exploit Status | Unpublished |
| KEV Status | Not Listed |
Out-of-bounds Read and Out-of-bounds Write due to miscompilation.