Where
-Infinity
0
Severity
7

Wasmtime is a runtime for WebAssembly. From 32.0.0 to before 36.0.7, 42.0.2, and 43.0.1, Wasmtime's Cranelift compilation backend contains a bug on aarch64 when performing a certain shape of heap accesses which means that the wrong address is accessed. When combined with explicit bounds checks a guest WebAssembly module this can create a situation where there are two diverging computations for the same address: one for the address to bounds-check and one for the address to load. This difference in address being operated on means that a guest module can pass a bounds check but then load a different address. Combined together this enables an arbitrary read/write primitive for guest WebAssembly when accesssing host memory. This is a sandbox escape as guests are able to read/write arbitrary host memory. This vulnerability has a few ingredients, all of which must be met, for this situation to occur and bypass the sandbox restrictions. This miscompiled shape of load only occurs on 64-bit WebAssembly linear memories, or when Config::wasmmemory64 is enabled. 32-bit WebAssembly is not affected. Spectre mitigations or signals-based-traps must be disabled. When spectre mitigations are enabled then the offending shape of load is not generated. When signals-based-traps are disabled then spectre mitigations are also automatically disabled. The specific bug in Cranelift is a miscompile of a load of the shape load(iadd(base, ishl(index, amt))) where amt is a constant. The amt value is masked incorrectly to test if it's a certain value, and this incorrect mask means that Cranelift can pattern-match this lowering rule during instruction selection erroneously, diverging from WebAssembly's and Cranelift's semantics. This incorrect lowering would, for example, load an address much further away than intended as the correct address's computation would have wrapped around to a smaller value insetad. This vulnerability is fixed in 36.0.7, 42.0.2, and 43.0.1.

First published (updated )
Severity
7

Wasmtime is a runtime for WebAssembly. From 30.0.0 to 36.0.8, 43.0.2, and 44.0.1, Wasmtime's allocation logic for a WebAssembly table contained checked arithmetic which panicked on overflow. This overflow is possible to trigger, and thus panic, when a table with an extremely large size is allocated. This is possible with the WebAssembly memory64 proposal where tables can have sizes in the 64-bit range as opposed to the previous 32-bit range which would not overflow. The panic happens when attempting to create a very large table, such as when instantiating a WebAssembly module or component. This vulnerability is fixed in 36.0.8, 43.0.2, and 44.0.1.

First published (updated )
Severity
2.3
CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Impact

Wasmtime's native implementation of WASIp1 suffers from a leak in the fdrenumber function where the file descriptor being renumbered to is not properly closed. Wasmtime's implementation erroneously only updated the table of descriptors for WASIp1 and didn't update the underlying table of descriptors used by the host. This behavior means that while fdrenumber works correctly from a guest's perspective it ends up leaking resources in the host that aren't cleaned up until the corresponding Store is destroyed. This means that guests can, in a loop, use fdrenumber to cause hosts to exhaust resources or exhaust file descriptors.

This bug only affects the native implementation of WASIp1. This means that only runtimes which load core wasm modules and expose fdrenumber are affected. Runtimes are additionally only affected if they expose the ability to acquire a file descriptor, such as opening a file. For runtimes that deny access to files they are unaffected.

Patches

Wasmtime 24.0.10, 36.0.11, 44.0.3, and 45.0.2 have been released which fix this issue.

Workarounds

There are no workarounds for this issue and hosts are recommended to update.

1 / 2
Source: GitHub
First published (updated )
Severity
1
CVSS:4.0/AV:A/AC:L/AT:P/PR:L/UI:P/VC:N/VI:N/VA:L/SC:N/SI:N/SA:L/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Impact

Wasmtime 37.0.0 and 37.0.1 have memory leaks in the C/C++ API when using bindings for the anyref or externref WebAssembly values. This is caused by a regression introduced during the development of 37.0.0 and all prior versions of Wasmtime are unaffected. If anyref or externref is not used in the C/C++ API then embeddings are also unaffected by the leaky behavior. The wasmtime Rust crate is unaffected by this leak.

Development of Wasmtime 37.0.0 included a refactoring in Rust of changing the old ManuallyRooted<T> type to a new OwnedRooted<T> type. This change was integrated into Wasmtime's C API but left the C API in a state which had memory leaks. Additionally the new ownership semantics around this type were not reflected into the C++ API, making it leak-prone. A short version of the change is that previously ManuallyRooted<T>, as the name implies, required manual calls to an "unroot" operation. If this was forgotten then the memory was still cleaned up when the wasmtimestoret itself was destroyed eventually. Documentation of when to "unroot" was sparse and there were already situations prior to 37.0.0 where memory would be leaked until the store was destroyed anyway. All memory, though, was always bound by the store, and destroying the store would guarantee that there were no memory leaks.

In migrating to OwnedRooted<T> the usage of the type in Rust changed. A manual "unroot" operation is no longer required and it happens naturally as a destructor of the OwnedRooted<T> type in Rust itself. These new resource ownership semantics were not fully integrated into the preexisting semantics of the C/C++ APIs in Wasmtime. A crucial distinction of OwnedRooted<T> vs ManuallyRooted<T> is that the OwnedRooted<T> type allocates host memory outside of the store. This means that if an OwnedRooted<T> is leaked then destroying a store does not release this memory and it's a permanent memory leak on the host. This led to a few distinct, but related, issues arising:

A typo in the wasmtimevalunroot function in the C API meant that it did not actually unroot anything. This meant that even if embedders faithfully call the function then memory will be leaked. If a host-defined function returned a wasmtime{externref,anyref}t value then the value was never unrooted. The C/C++ API no longer has access to the value and the Rust implementation did not unroot. This meant that any values returned this way were never unrooted. The goal of the C++ API of Wasmtime is to encode automatic memory management in the type system, but the C++ API was not updated when OwnedRooted<T> was added. This meant that idiomatic usage of the C++ API would leak memory due to a lack of destructors on values.

These issues have all been fixed in a 37.0.2 release of Wasmtime. The implementation of the C and C++ APIs have been updated accordingly and respectively to account for the changes of ownership here. For example wasmtimevalunroot has been fixed to unroot, the Rust-side implementation of calling an embedder-defined function will unroot return values, and the C++ API now has destructors on the ExternRef, AnyRef, and Val types. These changes have been made to the 37.0.x release branch in a non-API-breaking fashion. Changes to the 38.0.0 release branch (and main in the Wasmtime repository) include minor API updates to better accomodate the API semantic changes.

Patches

Wasmtime 37.0.2 has been released which fixes these issues. Users of 37.0.0 and 37.0.1 are recommended to upgrade. Users of 36.0.x and prior are unaffected and need not upgrade.

Workarounds

The only known workaround at this time is to avoid using externref and anyref in the C/C++ API of Wasmtime. If avoiding those types is not possible then it's required for users to update to mitigate the leak issue.

Remediations

The Wasmtime project will be looking more closely into improving the situation around testing the C and C++ APIs of Wasmtime in the near future. For example we plan to integrate ASAN testing to discover leaks and errors earlier on in the development process. We're also going to look into expanding the test coverage of the C/C++ APIs to catch issues like this earlier on in development in the future.

1 / 2
Source: GitHub
First published (updated )

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203