bug: instantiating a module with a huge 64-bit table aborts the process (std::length_error / std::bad_alloc in the noexcept TableInstance constructor)

Open
#5,558 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
62/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
cpp, wasm

Research direction

Start by reading the TableInstance constructors in include/runtime/instance/table.h and the instantiation path in Executor::instantiate for the table section. Check how allocation failures are handled so instantiation returns a recoverable error instead of terminating the process. Verify with the provided table64 module that instantiation fails without aborting.

Written by the indexing model from the issue text.

Description

Summary

A 23-byte module that declares a 64-bit table with a huge initial size aborts the process when it is instantiated: terminate called after throwing an instance of 'std::length_error' ('std::bad_alloc' from about 2^47 entries). The module is valid by the spec and by wasm-tools; V8 rejects it with a CompileError (implementation limit). A huge memory64 fails with an ordinary error (the memory page limit of the configuration).

Current State
(module (table i64 18446744073709551615 funcref))
printf '\x00asm\x01\x00\x00\x00\x04\x0d\x01\x70\x04\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01' > t.wasm     # 23 bytes
wasmedge t.wasm
terminate called after throwing an instance of 'std::length_error'
  what():  cannot create std::vector larger than max_size()
Aborted (core dumped)           # exit status 134
initial size of a table64 (funcref or externref, with or without a maximum) wasmedge node 24.22.1
2^64-1, 2^63, 2^62 abort, std::length_error CompileError: initial table size ... is larger than implementation limit (10000000 elements)
2^47 abort, std::bad_alloc CompileError (same)
2^40 still allocating after 60 s, 133 GB resident when stopped CompileError (same)
table32, 2^32-1 instantiates after 33 s with 64 GB resident (no abort, but no limit either) CompileError (same)
memory64, 2^47 pages Memory Instance: Limited 65536 page in configuration. (exit 1) CompileError (same)

wasm-tools validate --features all accepts the module (no error). The abort happens in Executor::instantiate(.., TableSection const&) (gdb: std::terminate <- __clang_call_terminate <- ModuleInstance::unsafeAddInstance<TableInstance, ...> <- Executor::instantiate).

Expected State

A recoverable error, as for the memory64 case (which has a page limit in the configuration; a table has none): the instantiation fails (the spec lets an implementation refuse a size it cannot allocate), the embedder keeps its process.

Reproduction steps
wasmedge t.wasm; echo $?        # 134 (t.wasm as above)
Root cause

include/runtime/instance/table.h: the constructors of TableInstance are noexcept and build the element vector from the declared minimum in the member initialiser list:

TableInstance(const AST::TableType &TType, const RefVariant &InitVal) noexcept
    : TabType(TType), Refs(TType.getLimit().getMin(), InitVal), ...

For a table64 the minimum is any uint64_t; std::vector(n, v) throws std::length_error above max_size() and std::bad_alloc when the allocation fails, and an exception leaving a noexcept function is std::terminate. A 32-bit table is at most 2^32-1 entries, which the vector accepts (the allocation succeeded in the measurement above). The same pattern is in TableInstance::growTable (Refs.resize(...), described in the closed PR #5498); this report is the instantiation path, which that PR does not touch.

Environment
  • Reproduced on master 3c3ce114ee (2026-11-11, head of master; pristine release build, clang-21 / LLVM 21.1.8, Ubuntu 22.04.5, x86_64, stock wasmedge, exit status 134) with the printf module above; first seen on 673031ab7e. The two constructors with Refs(TType.getLimit().getMin(), ...) in include/runtime/instance/table.h are unchanged at 3c3ce114ee.
  • Found by byte-level mutation of spec testsuite modules under ASAN (a mutant whose table limits were changed), reduced by hand.
  • Searched upstream issues and PRs (gh search, 2026-11-11) for table64 initial size, initial table size, unsafeAddInstance, TableInstance constructor, max_size vector, length_error, bad_alloc: nothing about this. Related: #4681 (a table of 10,000,001 entries is accepted; closed), PR #4812 (a 10M validator limit for 32-bit tables; closed unmerged), PR #5498 (table.grow; closed unmerged).
Components

Executor (instantiation)

Dominant language
C++
Stars
10.8k
Forks
1.2k
Avg merge
2d 23h
Merged PRs (30d)
48

Getting set up

This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from WasmEdge/WasmEdge

All issues in WasmEdge/WasmEdge

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.