Apr 10, 2026·8 min read·5 visits
A missing bounds check in the Wasmtime trampoline compiler allows guest components to supply arbitrary memory offsets during string transcoding, resulting in an out-of-bounds write on the host system.
Wasmtime fails to validate the return value of guest realloc functions during component string transcoding operations. This vulnerability allows a malicious WebAssembly guest component to direct the host runtime to write transcoded data outside the boundaries of the linear memory, resulting in a denial of service or potential memory corruption.
Wasmtime is a WebAssembly runtime supporting the WebAssembly Component Model. The Component Model facilitates complex data structure exchanges, such as strings, between independent WebAssembly components or between the guest and the host. When strings are transferred, the runtime frequently performs data transcoding, converting encodings such as UTF-8 to UTF-16 depending on the receiver's ABI requirements.
The vulnerability, tracked as CVE-2026-35195 (CWE-787), exists within the Fast Assembly Component Trampolines (FACT) compiler subsystem. The FACT compiler dynamically generates executable code to bridge these component interactions. The runtime fails to adequately validate the memory offset returned by a guest component's realloc function during these string transcoding operations.
An attacker-controlled guest component can exploit this oversight by returning an arbitrary 32-bit integer offset from its exported realloc function. The host runtime utilizes this unvalidated offset to calculate the destination memory address for the transcoded string bytes. This results in the host writing data up to 4GiB outside the intended bounds of the guest's linear memory.
The default impact is a Denial of Service. Wasmtime standard configurations allocate a 4GiB virtual memory reservation with guard pages for guest linear memory. Writing beyond this boundary causes the host process to fault on unmapped memory and abort. Environments operating with restricted memory reservations or disabled guard pages expose the host to out-of-bounds memory corruption.
The WebAssembly Component Model relies on the Canonical ABI to standardize data transfers. When a string requires transcoding, the destination component must supply an allocation buffer to receive the transformed data. The host achieves this by calling the guest's exported realloc function via a dynamically generated trampoline.
The defect originates in the FACT compiler, located within crates/environ/src/fact/trampoline.rs. The compiler generates the instructions for the trampoline but omits critical bounds and alignment validation logic for the 32-bit integer returned by the guest's realloc. The host assumes the returned offset represents a valid location within the component's linear memory.
The host resolves the absolute destination memory address by adding the unvalidated 32-bit offset to the base pointer of the guest's linear memory segment. Because the guest retains full control over the returned offset value, it can force the host to resolve a destination address up to 0xFFFFFFFF bytes away from the base pointer.
Following address resolution, the host runtime executes a memory copy operation or an optimized byte-write to transfer the transcoded string data. The host performs this write blindly to the attacker-specified memory location. The lack of secondary bounds checking on the calculated absolute pointer finalizes the out-of-bounds write condition.
The vulnerability was isolated to the dynamic code generation sequences in crates/environ/src/fact/trampoline.rs. Specifically, the issue resided in the code paths responsible for compiling the transcoding logic, such as converting UTF-8 to Latin1+UTF-16 or shrinking existing UTF-16 allocations.
In the vulnerable implementation, the FACT compiler emitted WebAssembly instructions to call realloc and subsequently stored the returned pointer index. The generated bytecode lacked any intermediate instructions to verify the safety or alignment of the pointer before using it as the base address for subsequent write operations.
The patch resolves the vulnerability by injecting explicit runtime validation constraints into the Wasm trampoline logic. The FACT compiler now emits instructions that strictly verify both the allocation boundaries and the target alignment constraints before proceeding with the memory write.
The patch adds self.verify_aligned() and self.validate_string_inbounds() directly after the realloc invocation. The verify_aligned function ensures the destination pointer meets the ABI requirements (e.g., 2-byte alignment for UTF-16). The validate_string_inbounds function calculates whether the returned offset combined with the string length exceeds the established linear memory boundaries.
// File: crates/environ/src/fact/trampoline.rs
// Patch snippet demonstrating the injected validation logic
// Emits the call to the guest realloc
self.instruction(Call(dst_mem_opts.realloc.unwrap().as_u32()));
// Stores the returned 32-bit offset
self.instruction(LocalSet(dst.ptr.idx));
// NEW: Verify 2-byte alignment for UTF-16 data
+ self.verify_aligned(dst_opts.data_model.unwrap_memory(), dst.ptr.idx, 2);
// NEW: Verify the offset + length fits within the linear memory bounds
+ self.validate_string_inbounds(&dst, dst_byte_len.idx);Exploitation requires the attacker to execute a malicious WebAssembly guest component within the target Wasmtime environment. The component must interact with an interface that invokes string transcoding between itself and either the host or another component. This satisfies the execution prerequisites.
The attacker constructs the malicious component by replacing or wrapping the standard realloc export. The manipulated function is programmed to return a highly specific, out-of-bounds 32-bit integer when requested to allocate space for the incoming transcoded string. The host captures this manipulated offset during the Canonical ABI transfer.
The attacker controls the payload data by supplying the original string content that triggers the transcoding operation. As the host performs the transcoding, it writes the attacker-controlled string bytes directly to the calculated out-of-bounds memory address. This grants the attacker precise spatial control over where the data is written relative to the linear memory base.
In default deployments utilizing 4GiB virtual memory reservations, the destination address falls within the unmapped guard region. The operating system traps the invalid write and terminates the host process. In environments without guard pages, the write silently overwrites adjacent host memory structures or the linear memory segments of other guests.
The baseline security impact of CVE-2026-35195 is Availability loss via Denial of Service. Under standard Wasmtime runtime configurations, the out-of-bounds write targets the designated guard pages. The subsequent operating system trap forces an immediate process termination, neutralizing the host application processing the WebAssembly module.
Environments customizing memory isolation parameters face significantly elevated risks. Implementations that restrict the virtual memory reservation size or explicitly disable protective guard pages transform the unhandled fault into an exploitable arbitrary memory overwrite condition. This severely degrades the integrity of the host runtime.
An arbitrary memory overwrite comprises a critical sandbox breach. An attacker can theoretically manipulate sensitive host data structures, alter instruction pointers, or tamper with the memory state of adjacent guest components. This culminates in a complete sandbox escape, granting the guest execution privileges on the host.
The vulnerability carries a CVSS 4.0 score of 6.1 (Medium). The base metric vector CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:L/VI:L/VA:H/SC:N/SI:N/SA:N highlights the low attack complexity and the requirement for low-level privileges inside the Wasm execution context. The primary assessed impact is the high availability impact against the host environment.
The discovery of CVE-2026-35195 resulted from a targeted three-week security sprint conducted by Wasmtime maintainers. Researchers from Mozilla, UCSD, Akamai, and F5 collaborated to audit the codebase using Large Language Model (LLM) security analysis tooling.
The audit methodology prioritized security-critical subsystems heavily reliant on unsafe Rust blocks and dynamic code generation. The dynamic trampoline generation logic in the FACT compiler presented a highly suitable target for automated semantic analysis due to its complex interaction with the WebAssembly ABI.
This specific out-of-bounds write was one of 11 distinct security vulnerabilities identified by the multi-agent LLM harness during the exercise. The research successfully demonstrates the efficacy of utilizing advanced semantic tooling to identify subtle logic flaws in complex compiler implementations that evade traditional fuzzing.
Remediation requires updating the Wasmtime runtime to a patched version. The Bytecode Alliance released fixes across all actively supported release lines. Organizations must upgrade to versions 24.0.7, 36.0.7, 42.0.2, or 43.0.1 depending on their current deployment branch.
No configuration workarounds exist to fully mitigate the flaw in vulnerable versions. Expanding memory reservations and enabling guard pages ensures the exploit results only in a crash, but this does not prevent the Denial of Service condition from occurring when a malicious guest is executed.
Organizations embedding Wasmtime must rebuild and redeploy their host applications using the updated crate versions. Recompiling the application ensures the FACT compiler correctly embeds the new bounds-checking and alignment-checking instructions into all dynamically generated trampolines at runtime.
Security teams should review their Wasmtime configuration parameters as a supplementary defense measure. Maintaining large virtual memory reservations and utilizing explicit guard pages remains a critical defense-in-depth practice to restrict the exploitability of spatial memory safety vulnerabilities.
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:L/VI:L/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Wasmtime bytecodealliance | < 24.0.7 | 24.0.7 |
Wasmtime bytecodealliance | >= 25.0.0, < 36.0.7 | 36.0.7 |
Wasmtime bytecodealliance | >= 37.0.0, < 42.0.2 | 42.0.2 |
Wasmtime bytecodealliance | >= 43.0.0, < 43.0.1 | 43.0.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-787 |
| Attack Vector | Network |
| CVSS 4.0 | 6.1 (Medium) |
| Impact | Availability Loss (High) / Potential Sandbox Escape |
| Exploit Status | None |
| KEV Status | Not Listed |
The software writes data past the end, or before the beginning, of the intended buffer.