WebAssembly / WebAssembly/wabt

Memory allocation error in ReadBinaryInterp() cause DoS

Open
#2,315 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C++
Stars
8.1k
Forks
827
Avg merge
4d 6h
Merged PRs (30d)
18

Description

Environments

OS : Ubuntu 18.04 5.4.0-150-generic
Commit : e97d53c5fcbb604fc36432df4fc117d13558d7fd
Version : 1.0.34

Vulnerability Description

Affected Tool : wasm-interp
Affected Version : <= 1.0.34
Impact : Denial of Service

  • The ReadBinaryInterp function in src/interp/binary-reader-interp.cc in wabt 1.0.34 can cause a denial of service(memory allocation error) via a crafted wasm file.

PoC

1. Input File

wasm-interp-DOS-poc01.zip

2. Reproduce

$ ~/wabt/bin/wasm-interp wasm-interp-DOS-poc01.wasm

3. Stack Trace

$  ~/wabt/bin/wasm-interp wasm-interp-DOS-poc01.wasm
==3917==AddressSanitizer's allocator is terminating the process instead of returning 0
==3917==If you don't like this behavior set allocator_may_return_null=1
==3917==AddressSanitizer CHECK failed: /build/llvm-toolchain-6.0-QjOn7h/llvm-toolchain-6.0-6.0/projects/compiler-rt/lib/sanitizer_common/sanitizer_allocator.cc:225 "((0)) != (0)" (0x0, 0x0)
    #0 0x4e5935 in __asan::AsanCheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/home/dskim/wabt/bin/wasm-interp+0x4e5935)
    #1 0x5031e5 in __sanitizer::CheckFailed(char const*, int, char const*, unsigned long long, unsigned long long) (/home/dskim/wabt/bin/wasm-interp+0x5031e5)
    #2 0x4ebd26 in __sanitizer::ReportAllocatorCannotReturnNull() (/home/dskim/wabt/bin/wasm-interp+0x4ebd26)
    #3 0x4ebd8d in __sanitizer::ReturnNullOrDieOnFailure::OnOOM() (/home/dskim/wabt/bin/wasm-interp+0x4ebd8d)
    #4 0x4276de in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) (/home/dskim/wabt/bin/wasm-interp+0x4276de)
    #5 0x427b27 in __asan::asan_memalign(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType) (/home/dskim/wabt/bin/wasm-interp+0x427b27)
    #6 0x514d5f in operator new(unsigned long) (/home/dskim/wabt/bin/wasm-interp+0x514d5f)
    #7 0x5b18fb in __gnu_cxx::new_allocator<wabt::interp::DataDesc>::allocate(unsigned long, void const*) /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/ext/new_allocator.h:111:27
    #8 0x5b18fb in std::allocator_traits<std::allocator<wabt::interp::DataDesc> >::allocate(std::allocator<wabt::interp::DataDesc>&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/alloc_traits.h:436
    #9 0x5b18fb in std::_Vector_base<wabt::interp::DataDesc, std::allocator<wabt::interp::DataDesc> >::_M_allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/stl_vector.h:172
    #10 0x5b18fb in wabt::interp::DataDesc* std::vector<wabt::interp::DataDesc, std::allocator<wabt::interp::DataDesc> >::_M_allocate_and_copy<std::move_iterator<wabt::interp::DataDesc*> >(unsigned long, std::move_iterator<wabt::interp::DataDesc*>, std::move_iterator<wabt::interp::DataDesc*>) /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/stl_vector.h:1260
    #11 0x5b18fb in std::vector<wabt::interp::DataDesc, std::allocator<wabt::interp::DataDesc> >::reserve(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/vector.tcc:73
    #12 0x596d95 in wabt::interp::(anonymous namespace)::BinaryReaderInterp::OnDataCount(unsigned int) /home/dskim/wabt/out/clang/Debug/asan/../../../../src/interp/binary-reader-interp.cc:756:17
    #13 0x6f28ce in wabt::(anonymous namespace)::BinaryReader::ReadDataCountSection(unsigned long) /home/dskim/wabt/out/clang/Debug/asan/../../../../src/binary-reader.cc:2846:3
    #14 0x6f28ce in wabt::(anonymous namespace)::BinaryReader::ReadSections(wabt::(anonymous namespace)::BinaryReader::ReadSectionsOptions const&) /home/dskim/wabt/out/clang/Debug/asan/../../../../src/binary-reader.cc:2969
    #15 0x6eef6e in wabt::(anonymous namespace)::BinaryReader::ReadModule(wabt::(anonymous namespace)::BinaryReader::ReadModuleOptions const&) /home/dskim/wabt/out/clang/Debug/asan/../../../../src/binary-reader.cc:3012:3
    #16 0x6eef6e in wabt::ReadBinary(void const*, unsigned long, wabt::BinaryReaderDelegate*, wabt::ReadBinaryOptions const&) /home/dskim/wabt/out/clang/Debug/asan/../../../../src/binary-reader.cc:3029
    #17 0x56b7df 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/dskim/wabt/out/clang/Debug/asan/../../../../src/interp/binary-reader-interp.cc:1604:10
    #18 0x51cbdd in ProgramMain(int, char**) /home/dskim/wabt/out/clang/Debug/asan/../../../../src/tools/wasm-interp.cc:324:3
    #19 0x7f7407598c86 in __libc_start_main /build/glibc-CVJwZb/glibc-2.27/csu/../csu/libc-start.c:310
    #20 0x41c929 in _start (/home/dskim/wabt/bin/wasm-interp+0x41c929)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the failure with the linked wasm-interp-DOS-poc01.wasm using wasm-interp, then inspect OnDataCount at src/interp/binary-reader-interp.cc:756 and its call from ReadBinaryInterp at line 1604. Use the stack trace to follow the data-count handling; done means the supplied crafted file is rejected or handled without an allocator termination.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, wasm
Domain
cli, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.