Project: wabt (webassembly/wabt), language: c++
Vulnerability instance: wabt.cve-2023-27117
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/WebAssembly/wabt/issues/1989
## Description:
Issue: WebAssembly/wabt#1989
Title: heap overflow in wabt::Node::operator=(wabt::Node&&)
State: open
Created by: Q1IQ
Created at: 2022-09-05 13:30:58+00:00
Labels: sanitizer failures

Issue Body:
### Environment
```
OS      : Linux ubuntu 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Commit  : 3054d61f703d609995798f872fc86b462617c294
Version : 1.0.29
Build   : make clang-debug-asan
```

### Proof of concept


[poc-2.wasm.zip](https://github.com/WebAssembly/wabt/files/9490159/poc-2.wasm.zip)


### Stack dump

```
=================================================================
==1704949==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x610000000010 at pc 0x0000005f2828 bp 0x7ffc769a3c60 sp 0x7ffc769a3c58
READ of size 4 at 0x610000000010 thread T0
    #0 0x5f2827 in wabt::Node::operator=(wabt::Node&&) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:67:17
    #1 0x5dc955 in wabt::Node::Node(wabt::Node&&) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:65:28
    #2 0x5f54b0 in std::enable_if<__and_<std::__not_<std::__is_tuple_like<wabt::Node>>, std::is_move_constructible<wabt::Node>, std::is_move_assignable<wabt::Node>>::value, void>::type std::swap<wabt::Node>(wabt::Node&, wabt::Node&) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/move.h:197:19
    #3 0x5f501e in void std::iter_swap<__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>>(__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_algobase.h:182:7
    #4 0x5f46ed in __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>> std::_V2::__rotate<__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>>(__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, std::random_access_iterator_tag) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_algo.h:1394:5
    #5 0x5dd60f in __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>> std::_V2::rotate<__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>>(__gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>, __gnu_cxx::__normal_iterator<wabt::Node*, std::vector<wabt::Node, std::allocator<wabt::Node>>>) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_algo.h:1439:14
    #6 0x5dd066 in wabt::AST::Construct(wabt::intrusive_list<wabt::Expr> const&, unsigned int, unsigned int, bool)::'lambda'(unsigned long)::operator()(unsigned long) const /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:279:11
    #7 0x5c8556 in wabt::AST::Construct(wabt::intrusive_list<wabt::Expr> const&, unsigned int, unsigned int, bool) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:307:13
    #8 0x5ee577 in void wabt::AST::Block<(wabt::ExprType)8>(wabt::BlockExprBase<(wabt::ExprType)8> const&, wabt::LabelType) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:159:5
    #9 0x5dc2fd in wabt::AST::Construct(wabt::Expr const&) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:212:9
    #10 0x5c7b64 in wabt::AST::Construct(wabt::intrusive_list<wabt::Expr> const&, unsigned int, unsigned int, bool) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:248:7
    #11 0x5c281f in wabt::Decompiler::Decompile[abi:cxx11]() /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:795:13
    #12 0x5be6bd in wabt::Decompile[abi:cxx11](wabt::Module const&, wabt::DecompileOptions const&) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:854:21
    #13 0x4f16bd in ProgramMain(int, char**) /wabt/out/clang/Debug/asan/../../../../src/tools/wasm-decompile.cc:103:18
    #14 0x4f2101 in main /wabt/out/clang/Debug/asan/../../../../src/tools/wasm-decompile.cc:116:10
    #15 0x7f9cae44d082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #16 0x43f04d in _start (/wabt/out/clang/Debug/asan/wasm-decompile+0x43f04d)

0x610000000010 is located 48 bytes to the left of 192-byte region [0x610000000040,0x610000000100)
allocated by thread T0 here:
    #0 0x4edc5d in operator new(unsigned long) /home/build-user/llvm-project/compiler-rt/lib/asan/asan_new_delete.cpp:95:3
    #1 0x5f05c8 in __gnu_cxx::new_allocator<wabt::Node>::allocate(unsigned long, void const*) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/ext/new_allocator.h:115:27
    #2 0x5f0570 in std::allocator_traits<std::allocator<wabt::Node>>::allocate(std::allocator<wabt::Node>&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/alloc_traits.h:460:20
    #3 0x5effaf in std::_Vector_base<wabt::Node, std::allocator<wabt::Node>>::_M_allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_vector.h:346:20
    #4 0x5f3462 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&&) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/vector.tcc:440:33
    #5 0x5f3124 in wabt::Node& std::vector<wabt::Node, std::allocator<wabt::Node>>::emplace_back<wabt::Node>(wabt::Node&&) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/vector.tcc:121:4
    #6 0x5dcbdc in std::vector<wabt::Node, std::allocator<wabt::Node>>::push_back(wabt::Node&&) /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_vector.h:1204:9
    #7 0x5de429 in wabt::AST::InsertNode(wabt::NodeType, wabt::ExprType, wabt::Expr const*, unsigned int) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:104:15
    #8 0x5dc5d0 in wabt::AST::Construct(wabt::Expr const&) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:230:9
    #9 0x5c7b64 in wabt::AST::Construct(wabt::intrusive_list<wabt::Expr> const&, unsigned int, unsigned int, bool) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:248:7
    #10 0x5ee577 in void wabt::AST::Block<(wabt::ExprType)8>(wabt::BlockExprBase<(wabt::ExprType)8> const&, wabt::LabelType) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:159:5
    #11 0x5dc2fd in wabt::AST::Construct(wabt::Expr const&) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:212:9
    #12 0x5c7b64 in wabt::AST::Construct(wabt::intrusive_list<wabt::Expr> const&, unsigned int, unsigned int, bool) /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:248:7
    #13 0x5c281f in wabt::Decompiler::Decompile[abi:cxx11]() /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:795:13
    #14 0x5be6bd in wabt::Decompile[abi:cxx11](wabt::Module const&, wabt::DecompileOptions const&) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:854:21
    #15 0x4f16bd in ProgramMain(int, char**) /wabt/out/clang/Debug/asan/../../../../src/tools/wasm-decompile.cc:103:18
    #16 0x4f2101 in main /wabt/out/clang/Debug/asan/../../../../src/tools/wasm-decompile.cc:116:10
    #17 0x7f9cae44d082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /wabt/out/clang/Debug/asan/../../../../src/decompiler-ast.h:67:17 in wabt::Node::operator=(wabt::Node&&)
Shadow bytes around the buggy address:
  0x0c207fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c207fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c207fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c207fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c207fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c207fff8000: fa fa[fa]fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c207fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c207fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c207fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c207fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c207fff8050: 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
==1704949==ABORTING

```


Comments:
Comment by rathann on 2023-03-17 12:04:27+00:00:
This is CVE-2023-27117.

Attachments:
https://github.com/WebAssembly/wabt/files/9490159/poc-2.wasm.zip

Commit References:
3054d61f703d609995798f872fc86b462617c294

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
mkdir -p build
cd build
cmake ..
cmake --build .

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y cmake libtool make python
RUN git clone https://github.com/webassembly/wabt wabt
RUN git -C wabt checkout c32fa597218dbe2c25b43a9837a8475b493ddb71
WORKDIR $SRC/wabt
COPY build.sh $SRC/

Additional files:
filename: wasm2wat_fuzzer.cc
content: // Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "wabt/src/binary-reader-ir.h"
#include "wabt/src/binary-reader.h"
#include "wabt/src/common.h"
#include "wabt/src/ir.h"

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
  wabt::ReadBinaryOptions options;
  wabt::Errors errors;
  wabt::Module module;
  wabt::ReadBinaryIr("dummy filename", data, size, options, &errors, &module);
  return 0;
}