Submit #719825: WebAssembly wabt 1.0.39 and master-branch Heap-based Buffer Overflowinfo

TitleWebAssembly wabt 1.0.39 and master-branch Heap-based Buffer Overflow
Description### Description We encountered a Heap-buffer-overflow vulnerability in the wasm-decompile tool. The crash occurs in wabt::AST::InsertNode when processing a specific WebAssembly binary. The AddressSanitizer (ASan) report indicates that the memory being accessed was freed during a std::vector reallocation (_M_realloc_insert). This suggests a Pointer Invalidation issue where a pointer/reference to a vector element is retained and dereferenced after the vector has been resized and its underlying memory freed. This issue was reproduced in a Release build (with NDEBUG defined), indicating it is a security vulnerability that affects production environments, potentially leading to Denial of Service (DoS) or memory corruption. ### Environment - OS: Linux x86_64 - Complier: Clang - Build Configuration: Release mode with ASan enabled. - Build Command: ``` make clang-release-asan CMAKE_FLAGS="-DCMAKE_BUILD_TYPE=Release -DUSE_ASAN=ON -DCMAKE_CXX_FLAGS_RELEASE=-DNDEBUG" ``` ### Vulnerability Details - Target: wasm-decompile - Crash Type: Heap-buffer-overflow (CWE-119 / CWE-416) - Faulting Instruction: READ of size 8 - Location: wabt::AST::InsertNode - Root Cause Analysis: The stack trace reveals the following sequence: 1. A std::vector<wabt::Node> undergoes reallocation (expansion) via std::vector::_M_realloc_insert. 2. The vector frees its old memory buffer (operator delete is called). 3. wabt::AST::InsertNode subsequently attempts to read from a memory address located in that old, freed buffer. 4. This implies that InsertNode is using a stale pointer or reference to a node that became invalid when the vector resized. ### Reproduce ``` ./wasm-decompile ./repro ``` Download Link: [repro](https://github.com/oneafter/1208/blob/main/af2) ASAN report ``` ==65981==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x510000000da0 at pc 0x557e6304794a bp 0x7ffc049d18d0 sp 0x7ffc049d18c8 READ of size 8 at 0x510000000da0 thread T0 #0 0x557e63047949 in wabt::AST::InsertNode(wabt::NodeType, wabt::ExprType, wabt::Expr const*, unsigned int) (/src/repro/wabt/bin/wasm-decompile+0x1c0949) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #1 0x557e6303fc7a in wabt::AST::Construct(wabt::intrusive_list<wabt::Expr> const&, unsigned int, unsigned int, bool) (/src/repro/wabt/bin/wasm-decompile+0x1b8c7a) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #2 0x557e63047141 in wabt::AST::Construct(wabt::Expr const&) (/src/repro/wabt/bin/wasm-decompile+0x1c0141) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #3 0x557e6303e83a in wabt::AST::Construct(wabt::intrusive_list<wabt::Expr> const&, unsigned int, unsigned int, bool) (/src/repro/wabt/bin/wasm-decompile+0x1b783a) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #4 0x557e630394f1 in wabt::Decompiler::Decompile[abi:cxx11]() (/src/repro/wabt/bin/wasm-decompile+0x1b24f1) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #5 0x557e630372a6 in wabt::Decompile[abi:cxx11](wabt::Module const&, wabt::DecompileOptions const&) (/src/repro/wabt/bin/wasm-decompile+0x1b02a6) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #6 0x557e62fd3941 in ProgramMain(int, char**) (/src/repro/wabt/bin/wasm-decompile+0x14c941) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #7 0x7f3decb4e1c9 (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #8 0x7f3decb4e28a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e) #9 0x557e62ef7584 in _start (/src/repro/wabt/bin/wasm-decompile+0x70584) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) 0x510000000da0 is located 2976 bytes after 192-byte region [0x510000000140,0x510000000200) freed by thread T0 here: #0 0x557e62fd1271 in operator delete(void*) (/src/repro/wabt/bin/wasm-decompile+0x14a271) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #1 0x557e6304b23f in void std::vector<wabt::Node, std::allocator<wabt::Node>>::_M_realloc_insert<wabt::Node>(__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, wabt::Node&&) (/src/repro/wabt/bin/wasm-decompile+0x1c423f) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) previously allocated by thread T0 here: #0 0x557e62fd09f1 in operator new(unsigned long) (/src/repro/wabt/bin/wasm-decompile+0x1499f1) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) #1 0x557e6304acfa in void std::vector<wabt::Node, std::allocator<wabt::Node>>::_M_realloc_insert<wabt::Node>(__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, wabt::Node&&) (/src/repro/wabt/bin/wasm-decompile+0x1c3cfa) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) SUMMARY: AddressSanitizer: heap-buffer-overflow (/src/repro/wabt/bin/wasm-decompile+0x1c0949) (BuildId: b44cadef6a2094e740cb6ce71ee9a45cfac22974) in wabt::AST::InsertNode(wabt::NodeType, wabt::ExprType, wabt::Expr const*, unsigned int) Shadow bytes around the buggy address: 0x510000000b00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000000b80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000000c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000000c80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000000d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x510000000d80: fa fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa 0x510000000e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000000e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000000f00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000000f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x510000001000: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==65981==ABORTING ```
Source⚠️ https://github.com/WebAssembly/wabt/issues/2679
User Oneafter (UID 92781)
Submission12/19/2025 10:46 (4 months ago)
Moderation01/01/2026 10:19 (13 days later)
StatusAccepted
VulDB entry339332 [WebAssembly wabt up to 1.0.39 wasm-decompile wabt::AST::InsertNode memory corruption]
Points20

Interested in the pricing of exploits?

See the underground prices here!