Skip to content

c-api: refresh cached Ref in C++ type copy assignment - #15109

Closed
netliomax25-code wants to merge 1 commit into
bytecodealliance:mainfrom
netliomax25-code:cpp-type-ref-copy-assign
Closed

netliomax25-code wants to merge 1 commit into
bytecodealliance:mainfrom
netliomax25-code:cpp-type-ref-copy-assign

Conversation

@netliomax25-code

Copy link
Copy Markdown
Contributor

Related: #15085, which fixes a different problem in other C++ copy assignment operators and does not touch these four classes.

FuncType, GlobalType, TableType and MemoryType cache a Ref ref next to the owning ptr, and operator-> and operator* hand out that cached ref. Their copy assignment replaces the owned object with ptr.reset(...) but does not update ref, so after b = a the cached pointer still refers to the object reset just freed, and b->params() reads freed memory. This needs nothing more unusual than assigning one existing value to another. __asan_describe_address on the pointer held by ref reports it as freed inside FuncType::operator=, and a debug build aborts in ty():

crates/c-api/src/types/func.rs:115:27:
unsafe precondition(s) violated: hint::unreachable_unchecked must never be reached

Move assignment copies ref along with ptr, and the existing tests assign from temporaries, which is likely why this went unnoticed. func_type.cc does copy-assign, but never reads the result.

The fix adds ref = ptr.get(); to all four operators, which is what TagType and ValType already do. Those two are the only other classes with a cached Ref. Only use through -> or * should be affected, since the other paths read ptr directly. The C++ API is tier 2 and the trigger is in embedder code, so I don't think this falls under the security process.

I added a CopyAssign test for each type. All four abort without the fix and pass with it. The C API job's ninja test (184 tests, Debug, -DBUILD_SHARED_LIBS=ON -DBUILD_TESTS=ON) passes on macOS aarch64 with and without -fsanitize=address, and clang-format 22 is clean. I have not run it on Linux or Windows.

FuncType, GlobalType, TableType and MemoryType cache a Ref next to the
owning ptr and hand it out from operator-> and operator*, but their copy
assignment only reset ptr, which left ref pointing at the object that
reset just freed. Update ref the same way TagType and ValType already do.
@netliomax25-code
netliomax25-code requested a review from a team as a code owner November 2, 2026 11:25
@netliomax25-code
netliomax25-code requested review from pchickey and removed request for a team November 2, 2026 11:25
@github-actions github-actions Bot added the wasmtime:c-api Issues pertaining to the C API. label Nov 2, 2026
@alexcrichton

Copy link
Copy Markdown
Member

Thanks for the PR, but this is a duplicate of #15098 which fixes another location as well, so I'm going to close this

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

wasmtime:c-api Issues pertaining to the C API.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants