VYPR
Low severity1.8OSV Advisory· Published Nov 12, 2025· Updated Apr 15, 2026

CVE-2025-64345

CVE-2025-64345

Description

Wasmtime is a runtime for WebAssembly. Prior to version 38.0.4, 37.0.3, 36.0.3, and 24.0.5, Wasmtime's Rust embedder API contains an unsound interaction where a WebAssembly shared linear memory could be viewed as a type which provides safe access to the host (Rust) to the contents of the linear memory. This is not sound for shared linear memories, which could be modified in parallel, and this could lead to a data race in the host. Patch releases have been issued for all supported versions of Wasmtime, notably: 24.0.5, 36.0.3, 37.0.3, and 38.0.4. These releases reject creation of shared memories via Memory::new and shared memories are now excluded from core dumps. As a workaround, eembeddings affected by this issue should use SharedMemory::new instead of Memory::new to create shared memories. Affected embeddings should also disable core dumps if they are unable to upgrade. Note that core dumps are disabled by default but the wasm threads proposal (and shared memory) is enabled by default.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
wasmtimecrates.io
>= 38.0.0, < 38.0.438.0.4
wasmtimecrates.io
>= 37.0.0, < 37.0.337.0.3
wasmtimecrates.io
>= 26.0.0, < 36.0.336.0.3
wasmtimecrates.io
< 24.0.524.0.5

Affected products

1

Patches

1
9ebb6934f00d

[38.0.x] Prevent using shared memories with `Memory` (#12020)

https://github.com/bytecodealliance/wasmtimeAlex CrichtonNov 11, 2025via ghsa
7 files changed · +65 4
  • crates/wasmtime/src/runtime/coredump.rs+8 2 modified
    @@ -41,7 +41,8 @@ impl WasmCoreDump {
         pub(crate) fn new(store: &mut StoreOpaque, backtrace: WasmBacktrace) -> WasmCoreDump {
             let modules: Vec<_> = store.modules().all_modules().cloned().collect();
             let instances: Vec<Instance> = store.all_instances().collect();
    -        let store_memories: Vec<Memory> = store.all_memories().collect();
    +        let mut store_memories: Vec<Memory> = store.all_memories().collect();
    +        store_memories.retain(|m| !m.wasmtime_ty(store).shared);
     
             let mut store_globals: Vec<Global> = vec![];
             store.for_each_global(|_store, global| store_globals.push(global));
    @@ -268,7 +269,12 @@ impl WasmCoreDump {
                         .all_memories(store.0)
                         .collect::<Vec<_>>()
                         .into_iter()
    -                    .map(|(_i, memory)| memory_to_idx[&memory.hash_key(&store.0)])
    +                    .map(|(_i, memory)| {
    +                        memory_to_idx
    +                            .get(&memory.hash_key(&store.0))
    +                            .copied()
    +                            .unwrap_or(u32::MAX)
    +                    })
                         .collect::<Vec<_>>();
     
                     let globals = instance
    
  • crates/wasmtime/src/runtime/memory.rs+3 0 modified
    @@ -285,6 +285,9 @@ impl Memory {
             limiter: Option<&mut StoreResourceLimiter<'_>>,
             ty: MemoryType,
         ) -> Result<Memory> {
    +        if ty.is_shared() {
    +            bail!("shared memories must be created through `SharedMemory`")
    +        }
             generate_memory_export(store, limiter, &ty, None).await
         }
     
    
  • crates/wast/Cargo.toml+1 1 modified
    @@ -15,7 +15,7 @@ workspace = true
     
     [dependencies]
     anyhow = { workspace = true }
    -wasmtime = { workspace = true, features = ['cranelift', 'wat', 'runtime', 'gc', 'async'] }
    +wasmtime = { workspace = true, features = ['cranelift', 'wat', 'runtime', 'gc', 'async', 'threads'] }
     wast = { workspace = true, features = ['dwarf'] }
     log = { workspace = true }
     tokio = { workspace = true, features = ['rt'] }
    
  • crates/wast/src/spectest.rs+1 1 modified
    @@ -80,7 +80,7 @@ pub fn link_spectest<T>(
     
         if config.use_shared_memory {
             let ty = MemoryType::shared(1, 1);
    -        let memory = Memory::new(&mut *store, ty)?;
    +        let memory = SharedMemory::new(store.engine(), ty)?;
             linker.define(&mut *store, "spectest", "shared_memory", memory)?;
         }
     
    
  • RELEASES.md+11 0 modified
    @@ -1,3 +1,14 @@
    +## 38.0.4
    +
    +Released 2025-11-11.
    +
    +### Fixed
    +
    +* Prevent using shared memories with `Memory`.
    +  [CVE-2025-64345](https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-hc7m-r6v8-hg9q)
    +
    +--------------------------------------------------------------------------------
    +
     ## 38.0.3
     
     Released 2025-10-24.
    
  • tests/all/coredump.rs+33 0 modified
    @@ -259,3 +259,36 @@ fn multiple_globals_memories_and_instances() -> Result<()> {
     
         Ok(())
     }
    +
    +#[test]
    +#[cfg_attr(miri, ignore)]
    +fn core_dump_with_shared_memory() -> Result<()> {
    +    if super::threads::engine().is_none() {
    +        return Ok(());
    +    }
    +    let mut config = Config::new();
    +    config.coredump_on_trap(true);
    +    let engine = Engine::new(&config)?;
    +    let mut store = Store::new(&engine, ());
    +    let wat = r#"(module
    +        (memory 1 1 shared)
    +        (func (export "foo") unreachable)
    +        (data (i32.const 0) "a")
    +    )"#;
    +    let module = Module::new(&engine, wat)?;
    +    let instance = Instance::new(&mut store, &module, &[])?;
    +    let foo = instance.get_typed_func::<(), ()>(&mut store, "foo")?;
    +    let err = foo.call(&mut store, ()).unwrap_err();
    +    let coredump = err.downcast_ref::<WasmCoreDump>().unwrap();
    +    assert!(coredump.memories().is_empty());
    +
    +    let bytes = coredump.serialize(&mut store, "howdy");
    +    for payload in wasmparser::Parser::new(0).parse_all(&bytes) {
    +        let payload = payload?;
    +        if let wasmparser::Payload::DataSection(s) = payload {
    +            assert_eq!(s.count(), 0);
    +        }
    +    }
    +
    +    Ok(())
    +}
    
  • tests/all/threads.rs+8 0 modified
    @@ -295,3 +295,11 @@ fn test_memory_size_accessibility() -> Result<()> {
     
         Ok(())
     }
    +
    +#[test]
    +fn create_shared_memory_through_memory() -> Result<()> {
    +    let engine = Engine::default();
    +    let mut store = Store::new(&engine, ());
    +    assert!(Memory::new(&mut store, MemoryType::shared(1, 1)).is_err());
    +    Ok(())
    +}
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.