Stream: git-wasmtime

Topic: wasmtime / PR #15085 c-api: fix use-after-free in C++ cop...


view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 06:36):

netliomax25-code opened PR #15085 from netliomax25-code:c-api-cpp-self-assignment to bytecodealliance:main:

Several copy assignment operators in the C++ headers release the current value before cloning from other, so when other is *this the clone reads the value that was just freed. Self-assignment usually arrives through an alias or a generic algorithm (for example std::fill over a range that contains the fill value). For component values the same thing happens when other is owned by the destination, which is a natural way to unwrap nested values:

Val v = WitOption(Val::string("..."));
v = *v.get_option().value(); // clones from the freed option payload

The affected operators are VAL_REPR (component Val, List, Record, Tuple, Variant, WitOption, WitResult, Flag, Flags, Map), WASMTIME_REF_WRAPPER (EqRef, StructRef, ArrayRef), core Val, HeapType, RefType, StorageType, FieldType, ValType, component ValType and ComponentItem. I checked each one with a small program that self-assigns a value, linked against a C API built with -Zsanitizer=address. All of them report heap-use-after-free except List and Record, where self-assignment silently leaves an empty value. For ExternRef and a core Val holding an externref, the assignment drops the last strong reference to the root's liveness flag and then clones it back from the raw pointer, so the flag is later freed while the store still holds a Weak to it and Store::gc reads freed memory.

Each operator now clones other before releasing the old value. Most of them copy-construct and then move-assign, since their move assignment already releases the old value. VAL_REPR snapshots the raw value instead, because constructor overload resolution there has to consider WitOption(std::optional<Val>) while Val is still incomplete. ValType clones into a local first, since its move assignment doesn't release the previous wasmtime_ty (that looks like a separate leak, which I left alone here).

I added a component.assign_from_self_or_child test to crates/c-api/tests/component/values.cc. Without the fix it fails (the list comes back with size 0, then reading the freed option payload trips an assertion). With the fix the C API ctest suite passes (181 tests, Debug, -DBUILD_SHARED_LIBS=ON -DBUILD_TESTS=ON, macOS aarch64), the gtest binary also passes when built with -fsanitize=address, and clang-format 22 is clean. Since the C++ API is tier 2 and the trigger is in embedder code, I don't think this falls under the security process, so I'm sending it as a regular PR.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 06:36):

netliomax25-code removed the review request for wasmtime-core-reviewers from PR #15085.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 06:36):

netliomax25-code requested wasmtime-core-reviewers for a review on PR #15085.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 06:36):

netliomax25-code requested dicej for a review on PR #15085.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 08:44):

github-actions[bot] added the label wasmtime:c-api on PR #15085.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 14:36):

:thumbs_up: alexcrichton submitted PR review.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 14:36):

alexcrichton commented on PR #15085:

TIL a new feature of C++...

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 14:36):

alexcrichton added PR #15085 c-api: fix use-after-free in C++ copy assignment operators to the merge queue.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 15:00):

:check: alexcrichton merged PR #15085.

view this post on Zulip Wasmtime GitHub notifications bot (Oct 30 2026 at 15:00):

alexcrichton removed PR #15085 c-api: fix use-after-free in C++ copy assignment operators from the merge queue.


Last updated: Oct 31 2026 at 23:03 UTC