Apr 10, 2026·6 min read·4 visits
Wasmtime instances running on x86-64 with SSE3 disabled are vulnerable to a Denial of Service caused by a compiler bug in Cranelift. The bug fuses an 8-byte load into a 16-byte pshufd instruction, crashing the host via an out-of-bounds read.
An out-of-bounds read vulnerability exists in the Cranelift x86-64 backend of Wasmtime. When SSE3 is disabled, incorrect instruction selection for the f64x2.splat operation results in a widened 16-byte memory load instead of the intended 8-byte load, leading to a process-level segmentation fault and Denial of Service.
Wasmtime utilizes the Cranelift code generator to translate WebAssembly bytecode into native machine code. Within Cranelift's x86-64 backend architecture, an instruction selection flaw exists in the handling of the f64x2.splat WebAssembly operation. This specific operation is designed to duplicate a 64-bit floating-point value across both lanes of a 128-bit vector register.
The vulnerability, tracked under CWE-125 (Out-of-bounds Read), occurs exclusively on x86-64 architectures where the SSE3 instruction set extension is disabled. Under these specific hardware or configuration conditions, the compiler attempts an invalid optimization by fusing an 8-byte memory load (f64.load) directly into a 16-byte vector operation. This causes the generated machine code to read 8 bytes beyond the intended linear memory boundary established by the WebAssembly instance.
The primary consequence is a Denial of Service (DoS) via a host process crash. If the out-of-bounds read crosses from an allocated memory block into an unmapped memory page, the host CPU generates a hardware page fault. In Wasmtime configurations where signals-based traps are disabled, this fault results in an unhandled process-level segmentation fault, terminating the entire host application immediately.
Cranelift relies on Instruction Selection Link Edition (ISLE) rules to map high-level WebAssembly operations to native assembly instructions. The f64x2.splat operator requires a 64-bit input to be loaded and broadcasted to a 128-bit XMM register. On x86-64 hosts with SSE3 enabled, Cranelift correctly selects the movddup instruction, which natively performs a safe 8-byte load and broadcast sequence.
When SSE3 is disabled, Cranelift enters a fallback path utilizing the pshufd (Packed Shuffle Doublewords) instruction. The targeted ISLE rule directed the compiler to emit pshufd using the source operand directly. Because the ISLE framework permits load folding, the src operand could represent a memory address rather than a pre-loaded register. If the source operand was a sinkable load, the instruction selector emitted pshufd xmm0, [addr].
The root cause lies in the hardware behavior of the pshufd instruction when supplied with a memory operand. The hardware instruction inherently expects a full 128-bit (16-byte) memory operand, whereas the WebAssembly linear memory model only guarantees the safety of the 8 bytes requested by the original f64.load. Consequently, the CPU hardware performs a 16-byte memory read starting from the base address, reading exactly 8 bytes beyond the validated bounds of the Wasm linear memory.
The vulnerability originates in the Cranelift compiler's ISLE rules for the x86-64 backend, specifically located in cranelift/codegen/src/isa/x64/lower.isle. The flawed rule allowed the splat operation's source operand to be passed directly to the x64_pshufd emission function. The lack of constraints on the operand type permitted a memory address to be folded directly into the instruction.
// Vulnerable ISLE rule
(rule 0 (lower (has_type $F64X2 (splat src)))
(x64_pshufd src 0b01_00_01_00))
// Patched ISLE rule
(rule 0 (lower (has_type $F64X2 (splat src)))
(x64_pshufd (put_in_xmm src) 0b01_00_01_00))The patch introduces the put_in_xmm helper function around the src operand. This helper explicitly forces the instruction selector to emit a scalar 8-byte memory load (such as movsd) into an XMM register before executing the shuffle operation. By decoupling the memory load from the pshufd instruction, the compiler ensures that the hardware performs exactly the required 8-byte read.
This fix completely addresses the root cause for this specific instruction sequence. The shuffle operation now operates safely on a populated register rather than directly resolving a memory address, preventing the hardware from fetching adjacent bytes from the linear memory space.
Exploitation requires strict environmental prerequisites. The target host must operate on an x86-64 architecture with SSE3 disabled, either at the hardware level or via specific Wasmtime runtime configuration flags. Additionally, the Wasmtime instance must be configured with signals-based-traps disabled, preventing the runtime's signal handlers from catching standard memory access violations.
The attacker must compile a crafted WebAssembly module that places an f64.load operation at the precise end of an allocated linear memory page. This loaded value must then be immediately consumed by an f64x2.splat instruction. The module must manipulate the memory layout such that the initial 8-byte load resides within valid Wasm linear memory, but the subsequent 8 bytes fall into an adjacent unmapped guard page.
Upon execution, Cranelift fuses the f64.load and f64x2.splat operations into a single pshufd instruction with a memory operand. The CPU executes the 16-byte read, fetching the first 8 bytes successfully but triggering a hardware page fault upon attempting to read the guard page. Without signals-based traps to intercept the fault, the operating system delivers a SIGSEGV signal to the Wasmtime host, terminating the process.
If guard pages are completely disabled, the instruction reads 8 bytes of adjacent host memory into the vector register. However, architectural constraints place this leaked data into the upper 64 bits of the 128-bit register. Because WebAssembly guest code lacks native instructions to access or extract the upper bits of this specific vector layout, the out-of-bounds data remains unobservable to the attacker, minimizing any information disclosure risks.
The primary impact of CVE-2026-34944 is a Denial of Service directed at the Wasmtime host application. A single malicious WebAssembly module can reliably crash the entire runtime environment. In multi-tenant systems where a single Wasmtime host executes modules from multiple untrusted users, this crash terminates all concurrent executions, fully compromising the availability of the service.
The vulnerability is assessed with a CVSS v4.0 score of 4.1 (Medium). The base vector CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N reflects the narrow environmental conditions required. The Attack Requirements (AT:P) modifier is driven by the necessity of a disabled SSE3 instruction set. The Availability impact (VA:H) is scored high due to the process-level termination.
The following sequence illustrates the fault propagation path required to trigger the process termination.
Organizations utilizing Wasmtime must upgrade to the official patched versions: 24.0.7, 36.0.7, 42.0.2, or 43.0.1. The maintainers have backported the compiler fix across multiple release lines to support environments maintaining older major versions. Updating the runtime directly replaces the flawed ISLE rule, ensuring that pshufd is never emitted with a memory operand during splat compilation.
For deployments unable to deploy patches immediately, configuration changes provide complete mitigation. Enabling the SSE3 instruction set extension in the host environment or compiler configuration forces Cranelift to use the safe movddup instruction path. Modern x86-64 hardware almost universally supports SSE3 natively, making this an effective workaround for the majority of bare-metal and virtualized environments.
Enabling signals-based-traps within the Wasmtime runtime configuration establishes a strong secondary defense. With this setting active, Wasmtime registers signal handlers that intercept hardware page faults. When the 16-byte read violates the guard page boundary, the runtime catches the fault and translates it into a standard WebAssembly trap, safely terminating only the offending module execution without affecting the host process.
CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:A/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Wasmtime Bytecode Alliance | < 24.0.7 | 24.0.7 |
Wasmtime Bytecode Alliance | >= 25.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, < 44.0.1 | 43.0.1 |
| Attribute | Detail |
|---|---|
| CWE | CWE-125: Out-of-bounds Read |
| Attack Vector | Local |
| CVSS v4.0 | 4.1 |
| Impact | Denial of Service (Crash) |
| Prerequisites | SSE3 disabled, Signals-based traps disabled |
| Exploit Status | Proof of Concept |
The software reads data past the end, or before the beginning, of the intended buffer.