bytecodealliance / bytecodealliance/wasmtime

`StoreContextMut::async_call_stack` use-after-free of a table index slot, leading to bail-bugs

Open
#14,247 0 comments 0 reactions 0 assignees View on GitHub
wasm-proposal:component-model-async
Dominant language
Rust
Stars
18.6k
Forks
1.8k
Avg merge
1d 19h
Merged PRs (30d)
121

Description

This function is based on the `GuestTask::caller` field, which is prone to use-after-free errors. Specifically, if a task creates a subtask and then exits before the subtask exits, the `caller` field will be a table index which is no longer valid, leading to an error at best or silently incorrect behavior at worst (e.g. if that index is reused for a different purpose) if it is used again.

Earlier versions of Wasmtime ensured that `GuestTask::caller` remained correct regardless of the order in which caller and callee exited. It did so by reparenting subtasks when their callers exited. However, that was based on an earlier version of the component model specification which is no longer relevant, so that code was removed.

One of the main motivations for adding `StoreContextMut::async_call_stack` was to support attributing a guest->host import call to a corresponding host->guest export call. However, that doesn't need the full call stack, just some sort of scalar identifier to uniquely represent the export call. One way to address that would be to provide an API for passing an embedder-supplied identifier when calling the guest and passing it along to any transitive subtasks created by that call. That identifier could be e.g. a UUID or an `Arc`, where `T` is a custom type that contains embedder-specific context for the call.

If the above approach suffices for attribution, we could remove `async_call_stack`. Alternatively, if we feel `async_call_stack` still has value for e.g. debugging and error reporting, we could restore the earlier Wasmtime behavior where each task keeps track of its subtasks and reparents them when it exits (with clear internal documentation that those fields are for debugging and error reporting only and not to be used in a "load bearing" way).

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.