WebAssembly / WebAssembly/wabt
Memory allocation error in ReadBinaryInterp() cause DoS
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
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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