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

================= Bug Report (1/1) ==================
## Source: GitHub Issue
## URL: https://github.com/WebAssembly/wabt/issues/1990
## Description:
Issue: WebAssembly/wabt#1990
Title: SEGV in wabt::Decompiler::WrapChild
State: open
Created by: Q1IQ
Created at: 2022-09-05 13:34:09+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-3.wasm.zip](https://github.com/WebAssembly/wabt/files/9490169/poc-3.wasm.zip)


### Stack dump

```
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1814123==ERROR: AddressSanitizer: SEGV on unknown address 0xffffffffffffffe8 (pc 0x7f12f2723bfe bp 0x7ffe034681e0 sp 0x7ffe03467e18 T0)
==1814123==The signal is caused by a READ memory access.
    #0 0x7f12f2723bfe in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::append(char const*, unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0x144bfe)
    #1 0x609269 in wabt::Decompiler::WrapChild(wabt::Decompiler::Value&, std::basic_string_view<char, std::char_traits<char>>, std::basic_string_view<char, std::char_traits<char>>, wabt::Decompiler::Precedence) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:125:18
    #2 0x619663 in wabt::Decompiler::BracketIfNeeded(wabt::Decompiler::Value&, wabt::Decompiler::Precedence) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:143:11
    #3 0x60ce08 in wabt::Decompiler::WrapBinary(std::vector<wabt::Decompiler::Value, std::allocator<wabt::Decompiler::Value>>&, std::basic_string_view<char, std::char_traits<char>>, bool, wabt::Decompiler::Precedence) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:153:5
    #4 0x5cfb8b in wabt::Decompiler::DecompileExpr(wabt::Node const&, wabt::Node const*) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:473:16
    #5 0x5ccb59 in wabt::Decompiler::DecompileExpr(wabt::Node const&, wabt::Node const*) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:357:22
    #6 0x5ccb59 in wabt::Decompiler::DecompileExpr(wabt::Node const&, wabt::Node const*) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:357:22
    #7 0x5ccb59 in wabt::Decompiler::DecompileExpr(wabt::Node const&, wabt::Node const*) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:357:22
    #8 0x5ccb59 in wabt::Decompiler::DecompileExpr(wabt::Node const&, wabt::Node const*) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:357:22
    #9 0x5ccb59 in wabt::Decompiler::DecompileExpr(wabt::Node const&, wabt::Node const*) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:357:22
    #10 0x5c30b4 in wabt::Decompiler::Decompile[abi:cxx11]() /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:825:20
    #11 0x5be6bd in wabt::Decompile[abi:cxx11](wabt::Module const&, wabt::DecompileOptions const&) /wabt/out/clang/Debug/asan/../../../../src/decompiler.cc:854:21
    #12 0x4f16bd in ProgramMain(int, char**) /wabt/out/clang/Debug/asan/../../../../src/tools/wasm-decompile.cc:103:18
    #13 0x4f2101 in main /wabt/out/clang/Debug/asan/../../../../src/tools/wasm-decompile.cc:116:10
    #14 0x7f12f2272082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #15 0x43f04d in _start (/wabt/out/clang/Debug/asan/wasm-decompile+0x43f04d)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libstdc++.so.6+0x144bfe) in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>::append(char const*, unsigned long)
==1814123==ABORTING

```


Comments:
Comment by rathann on 2023-03-17 12:06:11+00:00:
This is CVE-2023-27119.

---

Comment by kapouer on 2025-02-17 11:19:18+00:00:
Is this reproducible with `wasm-decompile poc-3.wasm` ?

---

Comment by rathann on 2025-02-18 09:28:39+00:00:
> Is this reproducible with `wasm-decompile poc-3.wasm` ?

No SIGSEGV with 1.0.36 on Fedora 41:
```
$ wasm-decompile --version
1.0.36
$ wasm-decompile poc-3.wasm 
0000080: error: function body must end with END opcode
```

---

Comment by kapouer on 2025-02-18 09:33:31+00:00:
I tried
> wasm-decompile --enable-all poc-3.wasm

with 1.0.36 on debian 13, same result.

I suppose it must be compiled with debug-asan flags to crash.

Attachments:
https://github.com/WebAssembly/wabt/files/9490169/poc-3.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;
}