WebAssembly / wabt

The WebAssembly Binary Toolkit
Apache License 2.0
6.78k stars 691 forks source link

Out-of-Memory Program Abort in BinaryReaderInterp::OnDataCount() #2397

Open mobsceneZ opened 6 months ago

mobsceneZ commented 6 months ago

Environment

OS               : Linux 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Commit           : 9fdd024249b6b181d98a4164700ca6ee09f970d9 - 1471dffee8bf9939044b80d34256956a28138e96
Version          : 1.0.33 (git~1.0.33-35-gdddc03d3)
Clang Verison    : 13.0.0
Build            : mkdir build && cd build && export CC=clang CXX=clang++ CFLAGS="-fsanitize=address -g" CXXFLAGS="-fsanitize=address -g" && cmake .. && cmake --build .
Affected Tool    : wasm-interp
Enabled Features : None
Impact           : OOM Program Abort (leading to DoS)

Proof of Concept

wasm-poc-02.zip

Stack Trace Provide By AddressSanitizer

=================================================================
==2681==ERROR: AddressSanitizer: allocator is out of memory trying to allocate 0x6330be8c8 bytes
    #0 0x519508 in operator new(unsigned long) /home/lain/llvm-project-llvmorg-13.0.0/compiler-rt/lib/asan/asan_new_delete.cpp:95
    #1 0x54e55b in __gnu_cxx::new_allocator<wabt::interp::DataDesc>::allocate(unsigned long, void const*) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/ext/new_allocator.h:114:27
    #2 0x54e500 in std::allocator_traits<std::allocator<wabt::interp::DataDesc> >::allocate(std::allocator<wabt::interp::DataDesc>&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/alloc_traits.h:443:20
    #3 0x54e4bf in std::_Vector_base<wabt::interp::DataDesc, std::allocator<wabt::interp::DataDesc> >::_M_allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:343:20
    #4 0x5f4c78 in std::vector<wabt::interp::DataDesc, std::allocator<wabt::interp::DataDesc> >::reserve(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/vector.tcc:78:22
    #5 0x5b03ea in wabt::interp::(anonymous namespace)::BinaryReaderInterp::OnDataCount(unsigned int) /home/lain/wabt_asan/src/interp/binary-reader-interp.cc:756:17
    #6 0x702894 in wabt::(anonymous namespace)::BinaryReader::ReadDataCountSection(unsigned long) /home/lain/wabt_asan/src/binary-reader.cc:2846:3
    #7 0x6ecfe5 in wabt::(anonymous namespace)::BinaryReader::ReadSections(wabt::(anonymous namespace)::BinaryReader::ReadSectionsOptions const&) /home/lain/wabt_asan/src/binary-reader.cc:2969:26
    #8 0x6e9d0f in wabt::(anonymous namespace)::BinaryReader::ReadModule(wabt::(anonymous namespace)::BinaryReader::ReadModuleOptions const&) /home/lain/wabt_asan/src/binary-reader.cc:3012:3
    #9 0x6e8d01 in wabt::ReadBinary(void const*, unsigned long, wabt::BinaryReaderDelegate*, wabt::ReadBinaryOptions const&) /home/lain/wabt_asan/src/binary-reader.cc:3029:17
    #10 0x58d752 in wabt::interp::ReadBinaryInterp(std::basic_string_view<char, std::char_traits<char> >, void const*, unsigned long, wabt::ReadBinaryOptions const&, std::vector<wabt::Error, std::allocator<wabt::Error> >*, wabt::interp::ModuleDesc*) /home/lain/wabt_asan/src/interp/binary-reader-interp.cc:1604:10
    #11 0x5255ed in ReadModule(char const*, std::vector<wabt::Error, std::allocator<wabt::Error> >*, wabt::interp::RefPtr<wabt::interp::Module>*) /home/lain/wabt_asan/src/tools/wasm-interp.cc:324:3
    #12 0x51fa08 in ReadAndRunModule(char const*) /home/lain/wabt_asan/src/tools/wasm-interp.cc:351:19
    #13 0x51ecf7 in ProgramMain(int, char**) /home/lain/wabt_asan/src/tools/wasm-interp.cc:450:25
    #14 0x51ff21 in main /home/lain/wabt_asan/src/tools/wasm-interp.cc:456:10
    #15 0x7fb26ffa4082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

==2681==HINT: if you don't care about these errors you may set allocator_may_return_null=1
SUMMARY: AddressSanitizer: out-of-memory /home/lain/llvm-project-llvmorg-13.0.0/compiler-rt/lib/asan/asan_new_delete.cpp:95 in operator new(unsigned long)
==2681==ABORTING