Advisory · CVE-2026-115384
Wasmtime async callback results are not validated, overflowing the native stack and escaping the sandbox
Wasmtime 39.0.0 before 48.0.4 and 49.0.0 before 49.0.2 does not validate the result types of component-model-async callback functions, so a malicious guest can write about 16 KB of chosen data to the native stack, overwrite return addresses, crash the host or escape the sandbox. CVSS 3.1 9.9.
- Vendor
- Bytecode Alliance
- Product
- Wasmtime
- Identifier / CWE
- CVE-2026-115384
CWE-20 - Action timing
- Immediate
Explain it like I’m five
Wasmtime trusts a checklist that was supposed to confirm a guest function returns one small value. The checklist had a typo, so a guest can claim to return a truckload instead, and the extra cargo lands on the host stack where return addresses live.
- 01Attacker supplies a crafted component
A malicious guest component uses a component-model-async callback function with a mistyped signature, declaring far more results than the real callback type allows.
- 02Validation accepts it
Per the Wasmtime advisory, the validator logic for async-lifted callback signatures was incorrect and accepted invalid components instead of rejecting them, and later stages trusted that validation.
- 03Callback writes past its area
When the runtime calls the callback, it allocates a return area on the native stack matching the expected arity rather than the actual one, with no bounds check in the generated trampoline.
- 04Native stack is overwritten
The guest writes up to about 16 KB of chosen data to the native stack, overwriting return addresses, which Wasmtime states can pass control to arbitrary host code or crash the process.
What happened
The Bytecode Alliance disclosed CVE-2026-115384 in its Wasmtime security advisory: Wasmtime did not properly validate the return types of core functions used as component-model-async callback functions, which can allow a guest to write up to about 16 KB of arbitrary data of its choosing to the process native stack. Since the guest can write data of its choosing to the native stack, it can overwrite return addresses, which can then be used to pass control to arbitrary host code or crash the process. The CVE record lists Wasmtime 39.0.0 before 48.0.4 and 49.0.0 before 49.0.2 as affected. The CVSS 3.1 score is 9.9, with changed scope.
Per the advisory, the validation of async-lifted callback signatures in the component validator was incorrect due to a typographic error: it checked the parameters but not the result types, and the compiler and runtime stages that followed trusted that validation instead of checking the arity themselves. Wasmtime states that embedders should treat this as an arbitrary code execution sandbox escape vulnerability, even though operating system features such as address space layout randomization and a non-executable stack can thwart simple attempts. Wasmtime 48.0.4 and 49.0.2 have been released with a fix. As a workaround, the advisory states the issue can be avoided by disabling the component-model-async feature, in which case Wasmtime rejects components that use any async features.
What to do
- Inventory applications and services that embed Wasmtime, including plug-in hosts, edge runtimes and serverless platforms, and note the Wasmtime version each ships.
- Upgrade affected embeddings to Wasmtime 48.0.4 or 49.0.2 or later for the branch in use, using the Bytecode Alliance release guidance.
- If an embedding cannot be upgraded immediately and does not need async components, disable the component-model-async feature as the advisory workaround, so async components are rejected.
- Treat components from untrusted sources as hostile until patched: review which tenants or users can supply components that use async callbacks, and look for host crashes consistent with stack corruption.
- Verify the deployed Wasmtime version in every embedding after updating, including statically linked binaries.
Management note
A sandbox escape in Wasmtime breaks the core promise embedders build multi-tenant platforms on. Anything that runs untrusted components with async features enabled should be patched on the emergency ring, not the routine one.