CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-104855

CVE-2026-104855: Sandbox Escape via Reentrant State Desynchronization in Wasmtime Bulk Memory Operations

Amit Schendel
Amit Schendel
Senior Security Researcher

Oct 3, 2026·7 min read·2 visits

Executive Summary (TL;DR)

A state desynchronization flaw in Wasmtime's bulk operations allowed host reentrancy during loop preemption checks. Under specific configurations, a callback could modify the linear memory layout or garbage-collection heap, causing the resumed loop to perform use-after-free operations or out-of-bounds writes, potentially leading to WebAssembly sandbox escape.

CVE-2026-104855 is a critical vulnerability involving a race condition and reentrant state desynchronization within Wasmtime, a standalone WebAssembly runtime. Due to incremental mid-operation preemption points in compiler-generated loops for bulk memory and table operations, a host-defined epoch or fuel deadline callback could mutate the WebAssembly Store. Upon resuming, the virtual machine utilized stale cached pointers, resulting in use-after-free, out-of-bounds writes, and sandbox escape.

Vulnerability Overview

The affected component is the Cranelift compiler within Wasmtime, specifically the logic responsible for translating bulk operations such as memory.copy, table.grow, and array.copy into target-specific machine instructions. WebAssembly bulk operations are inherently expensive because they process large contiguous buffers or table structures in a single logical instruction. In multi-tenant environments, executing these instructions monolithically could block the execution thread, circumventing scheduling constraints and deadline mechanisms. To prevent thread monopolization, Wasmtime's compiler partitioned these bulk operations into chunked loops interspersed with preemption points.

These preemption points were designed to check current fuel levels and epoch-based deadlines. When an epoch expired or fuel was exhausted, control returned to the host embedder via a user-defined callback. This architecture created an unexpected reentrancy vector where the host application could execute arbitrary code, modify VM state, or trigger garbage collection before yielding execution back to the guest. Consequently, the assumption of atomic execution during bulk operations was violated.

The security boundary breached is the WebAssembly sandbox itself. WebAssembly relies on strict memory isolation and type safety to guarantee that guest code cannot access host memory or other guest instances. By allowing the host to mutate internal store structures mid-operation, the compiler's assumptions about pointer validity were invalidated, converting safe WebAssembly operations into native memory corruption vulnerabilities.

Root Cause Analysis

The underlying bug is classified as a concurrent execution synchronization issue, mapping specifically to CWE-362 (Race Condition) and CWE-825 (Expired Pointer Dereference). The root cause lies in how the Cranelift compiler optimized bulk memory operations by caching native pointers. Before entering a chunked loop (such as one executing a memory.copy instruction), the compiled machine code resolved the base address of the WebAssembly linear memory and stored it in a CPU register or a stack slot to avoid the overhead of resolving it on every iteration.

If the cooperative preemption check triggered during an iteration, the WebAssembly virtual machine suspended execution and invoked the host-defined Store::epoch_deadline_callback. Because the callback is fully custom, it could perform actions that modified the layout of the WebAssembly store. For instance, the host could call memory.grow, which often forces Wasmtime to reallocate the linear memory buffer to a new virtual memory address, freeing the previous memory space.

Once the host callback completed and returned execution to the guest, the compiled loop resumed at the next chunk boundary. However, the machine code did not re-evaluate or re-resolve the base pointer of the linear memory. Instead, it continued writing data using the stale, cached base pointer that now pointed to deallocated native memory. This state desynchronization bypassed the bounds checks enforced at the start of the instruction, yielding a classic use-after-free or out-of-bounds write primitive.

Code Analysis and Vulnerable Code Paths

Within crates/cranelift/src/func_environ.rs, the Cranelift compiler managed the compilation of bulk memory operations through helper functions like raw_bulk_memory_operation and manual fuel check injection functions. The compiler would insert a manual_fuel_check or an epoch_check inside loop headers generated for bulk instructions. These checks called back into the runtime when thresholds were crossed, leaving the execution state partially suspended while waiting for the host to handle the yield.

// Vulnerable compiler logic that inserted mid-operation checks:
fn manual_fuel_check(&mut self, builder: &mut FunctionBuilder<'_>, fuel_to_consume: ir::Value) {
    self.fuel_increment_var(builder);
 
    let fuel = builder.use_var(self.fuel_var);
    let fuel = builder.ins().iadd(fuel, fuel_to_consume);
    builder.def_var(self.fuel_var, fuel);
 
    self.fuel_check(builder);
}

The compiled loop structure can be conceptualized using the following diagram, showing how the preemption check breaks the assumption of atomicity.

Additionally, in table.grow operations, Wasmtime temporarily populated newly allocated slots with null references before completing the fill process with target initialization references. If preemption occurred mid-loop and the host decided to abort execution or trap, the table remained in an intermediate, partially initialized state. Because non-nullable tables enforce the invariant that references must never be null, subsequent operations on these tables assumed type safety, leading to type confusion and native segmentation faults when dereferencing the unexpected null values.

Exploitation Methodology & Reentrancy Vectors

To trigger this vulnerability, an attacker must first be able to execute arbitrary WebAssembly payloads on a host that implements cooperative preemption via epoch-based deadlines or fuel metering. The host application must also configure a reentrant or state-modifying callback. In a typical exploitation scenario, the attacker crafts a WebAssembly module containing a large memory.copy or array.copy operation designed to cross multiple chunk boundaries and force a preemption event.

The timing of the preemption is critical. If the host uses epoch-based deadlines, the background epoch thread must increment the epoch precisely while the bulk operation loop is executing. Once the loop triggers the preemption, control flows to the host callback. Inside this callback, the attacker-controlled host environment or a misconfigured handler triggers a memory reallocation event (e.g., calling memory.grow from a concurrent thread or within the reentrant context) or initiates a garbage collection cycle.

During garbage collection, reference-typed pointers on the GC heap are compacted and moved to optimize memory layout. When the callback finishes and the VM resumes the chunked loop, the stored references inside the CPU registers are now pointing to invalid memory. The resumed copy operation then writes guest-controlled data directly to these obsolete addresses, giving the attacker a powerful read-and-write primitive over the host process's virtual address space.

Impact Assessment & Sandbox Escape Mechanics

The security impact of CVE-2026-104855 is severe, as it directly undermines the core safety guarantees of the WebAssembly execution model. Although the CVSS score is computed as 2.0 (Low) due to the high complexity and the requirement for specific host configurations, the real-world impact in vulnerable configurations is a complete sandbox escape. An attacker with the ability to write to arbitrary native memory locations can overwrite host execution pointers, such as function pointers or return addresses on the stack.

By corrupting the host process's memory space, the guest code can transition from restricted WebAssembly instructions to executing arbitrary native code on the host process. This allows the attacker to inherit the full permissions of the host process, potentially leading to unauthorized data access, local privilege escalation, or lateral movement within the hosting network.

Furthermore, because this flaw corrupts the underlying memory allocator and GC structures, it can cause unstable VM states that manifest as intermittent native crashes. In multi-tenant environments, such as cloud-native edge computing platforms or serverless database extensions, this vulnerability could allow one tenant to read or modify the state of other tenants sharing the same host process.

Remediation & Patch Verification

The vulnerability has been addressed by removing the incremental preemption checks inside bulk operation loops. In commits 3ebfbe5af4927c157d6fcaca42b8dbb6d17b73fb (v47.0.3) and 99b0bc39d447317a4102c056081c83a9a84a46e0 (v46.0.2), the Cranelift compiler was refactored to perform a single, atomic preemption check before commencing the bulk memory operation. This upfront validation calculates the total fuel cost of the operation and verifies the epoch deadline before any data transfer begins.

// Patched compiler code implementing upfront checks:
fn pre_translate_bulk_op(
    &mut self,
    builder: &mut FunctionBuilder,
    cost: ir::Value,
) -> WasmResult<()> {
    let const_cost =
        Self::value_as_const_int(builder, cost).map(|c| i64::try_from(c).unwrap_or(i64::MAX));
 
    if self.tunables.consume_fuel {
        // Fold constant costs or dynamically increment fuel up front
        // ...
    }
 
    const SMALL_BULK_OP_COST: i64 = 128;
    if let Some(cost) = const_cost && cost <= SMALL_BULK_OP_COST {
        return Ok(());
    }
 
    self.translate_loop_header(builder)
}

By transitioning to atomic checks, the compiled code guarantees that once a bulk memory operation starts, it executes to completion without yielding back to the host. This eliminates the reentrancy vector entirely. To verify the completeness of the fix, security teams should ensure that all instances of Wasmtime are upgraded to version 46.0.2, 47.0.3, or higher, and verify that any custom resource limiters are configured to prevent thread-blocking abuse from large, non-preemptible bulk operations.

Official Patches

bytecodeallianceGitHub Security Advisory
bytecodeallianceWasmtime Main Fix Commit

Fix Analysis (3)

Technical Appendix

CVSS Score
2.0/ 10
CVSS:4.0/AV:N/AC:H/AT:P/PR:H/UI:P/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N

Affected Systems

Wasmtime standalone WebAssembly runtime

Affected Versions Detail

Product
Affected Versions
Fixed Version
Wasmtime
Bytecode Alliance
>= 46.0.0, < 46.0.246.0.2
Wasmtime
Bytecode Alliance
>= 47.0.0, < 47.0.347.0.3
AttributeDetail
CWE IDCWE-362 (Concurrent Execution using Shared Resource with Improper Synchronization)
Attack VectorNetwork / Local
CVSS Score2.0 (Low Base / Critical Downstream Impact)
EPSS ScoreNot Listed
ImpactSandbox Escape, Memory Corruption (Use-After-Free, Out-of-Bounds Write)
Exploit StatusProof-of-Concept
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1068Exploitation for Privilege Escalation
Privilege Escalation
CWE-362
Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')

The software performs multiple concurrent operations on a shared resource, but does not properly synchronize access, leading to unexpected behaviors or race conditions.

Vulnerability Timeline

Wasmtime developers backport patches and release fixed versions 46.0.2 and 47.0.3
2026-07-31
GitHub Advisory GHSA-2hw9-mc66-jc2q published and CVE-2026-104855 assigned
2026-10-02

References & Sources

  • [1]GHSA-2hw9-mc66-jc2q
  • [2]CVE-2026-104855 Record

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•GHSA-FJ2X-MQQP-3V2W
7.5

GHSA-FJ2X-MQQP-3V2W: Sensitive Information Disclosure in Trigger.dev CLI Build Logs

A sensitive information disclosure vulnerability exists in the Trigger.dev Command Line Interface (CLI) framework. When executing build processes inside CLI v3 packages, the framework's debug deployment logs print unredacted, resolved environment variables and secrets to standard output or log streams. This exposure occurs when the CLI is operated with a high logging verbosity level, enabling any individual or automated system with read access to build logs, CI/CD output consoles, or local development streams to capture plaintext sensitive parameters, such as database credentials, API keys, and private external integration tokens.

Alon Barad
Alon Barad
2 views•6 min read
•about 3 hours ago•CVE-2026-74802
8.2

CVE-2026-74802: Cross-Site WebSocket Hijacking (CSWSH) in SiYuan Knowledge Workspace

CVE-2026-74802 is a critical Cross-Site WebSocket Hijacking (CSWSH) vulnerability in the SiYuan knowledge workspace application. Due to improper origin validation across multiple internal WebSocket endpoints, an attacker can hijack active authenticated sessions when a victim visits an untrusted external page. This allows the attacker to route malicious network traffic through the victim's localized SiYuan server, establishing an authenticated network pivot and facilitating Server-Side Request Forgery (SSRF).

Alon Barad
Alon Barad
3 views•5 min read
•about 4 hours ago•CVE-2026-74904
8.7

CVE-2026-74904: Missing Authorization in SiYuan Note-Taking Application API

A high-severity missing authorization vulnerability (CWE-862) exists in the SiYuan note-taking application before v3.7.4. Seventeen block metadata and content-derived endpoints within kernel/api/block.go lack proper publish-access and role-based checks. This allows low-privilege or anonymous users in publish mode to bypass workspace restrictions and disclose private block content, trace workspace structures, map document indexes, and verify the existence of private notes. The vulnerability is addressed in version v3.7.4.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 5 hours ago•CVE-2026-71416
8.8

CVE-2026-71416: Cross-Site WebSocket Hijacking in Headroom Proxy Server

A critical cross-site WebSocket hijacking (CSWSH) vulnerability in headroomlabs-ai/headroom prior to version 0.35.0 allows unauthorized external origins to establish connection channels to the Headroom proxy, enabling arbitrary prompt execution and remote code execution through local tool integration.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 6 hours ago•GHSA-CJCG-CXMH-9WCR
7.5

GHSA-cjcg-cxmh-9wcr: Unbounded Memory Allocation via HTTP/2 Bomb in praxis-proxy

A critical vulnerability exists in the praxis-proxy library where the omission of default limits on HTTP/2 server options allows remote attackers to trigger a Denial of Service (DoS) using an HPACK compression bomb and flow-control window stalls. This vulnerability is cataloged as GHSA-cjcg-cxmh-9wcr.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 7 hours ago•GHSA-MWM8-39RW-8826
8.1

GHSA-MWM8-39RW-8826: Use-After-Free Vulnerability in Ruby sqlite3 Gem native extension

A Use-After-Free (UAF) vulnerability exists in the sqlite3-ruby native C extension when marshaling arguments for user-defined SQLite aggregate functions with multiple arguments. Due to temporary heap-allocated argument arrays not being registered with the Ruby Garbage Collector, active objects can be prematurely reclaimed, resulting in memory corruption or process-level crashes.

Alon Barad
Alon Barad
5 views•7 min read