Skip to content

StoreContextMut::async_call_stack use-after-free #14247

Description

@dicej

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<T>, 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions