-
Notifications
You must be signed in to change notification settings - Fork 828
Open
Description
Desciprtion
We discovered a Heap Buffer Overflow vulnerability in wasm-opt. The crash occurs within the WasmBinaryReader::readExpression function when parsing a malformed WebAssembly binary.
The issue appears to be an Out-of-Bounds Read where the parser attempts to read a byte past the end of the input buffer, specifically while processing Data Segments.
Environment
- OS: Linux x86_64
- Complier: Clang with -fsanitize=address
- Tools: AddressSanitizer
Vulnerability Details
- Target: wasm-opt
- Vulnerability Type: Heap Buffer Overflow
- Location: src/wasm/wasm-binary.cpp:4736
The ASAN report indicates the crash happens immediately after a memory allocation for the file content, suggesting the parser reaches the EOF unexpectedly but tries to consume more bytes.
Reproduce
./wasm-opt repro -o /dev/null
Download Link: repro
ASAN report
==27855==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x512000000450 at pc 0x7fcc583639f6 bp 0x7ffe4a441f50 sp 0x7ffe4a441f48
READ of size 1 at 0x512000000450 thread T0
#0 0x7fcc583639f5 in wasm::WasmBinaryReader::readExpression() /src/binaryen/src/wasm/wasm-binary.cpp:4736:10
#1 0x7fcc58326082 in wasm::WasmBinaryReader::readDataSegments() /src/binaryen/src/wasm/wasm-binary.cpp:4865:22
#2 0x7fcc58306962 in wasm::WasmBinaryReader::read() /src/binaryen/src/wasm/wasm-binary.cpp:2092:9
#3 0x7fcc583bd63c in wasm::ModuleReader::readBinaryData(std::vector<char, std::allocator<char>>&, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) /src/binaryen/src/wasm/wasm-io.cpp:67:10
#4 0x7fcc583bddc7 in wasm::ModuleReader::readBinary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) /src/binaryen/src/wasm/wasm-io.cpp:78:3
#5 0x7fcc583bf68d in wasm::ModuleReader::read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) /src/binaryen/src/wasm/wasm-io.cpp:101:5
#6 0x55b42ff0568c in main /src/binaryen/src/tools/wasm-opt.cpp:319:14
#7 0x7fcc5503f1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#8 0x7fcc5503f28a in __libc_start_main csu/../csu/libc-start.c:360:3
#9 0x55b42fb7a164 in _start (/src/binaryen/build/bin/wasm-opt+0x7a164) (BuildId: 0854baef848e0e3aca2fa54cd3656fe250c93259)
0x512000000450 is located 0 bytes after 272-byte region [0x512000000340,0x512000000450)
allocated by thread T0 here:
#0 0x55b42fc5b611 in operator new(unsigned long) (/src/binaryen/build/bin/wasm-opt+0x15b611) (BuildId: 0854baef848e0e3aca2fa54cd3656fe250c93259)
#1 0x7fcc5811c2fd in std::__new_allocator<char>::allocate(unsigned long, void const*) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/new_allocator.h:151:27
#2 0x7fcc5811c2fd in std::allocator_traits<std::allocator<char>>::allocate(std::allocator<char>&, unsigned long) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/alloc_traits.h:482:20
#3 0x7fcc5811c2fd in std::_Vector_base<char, std::allocator<char>>::_M_allocate(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_vector.h:381:20
#4 0x7fcc5811c2fd in std::_Vector_base<char, std::allocator<char>>::_M_create_storage(unsigned long) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_vector.h:398:33
#5 0x7fcc5811c2fd in std::_Vector_base<char, std::allocator<char>>::_Vector_base(unsigned long, std::allocator<char> const&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_vector.h:335:9
#6 0x7fcc5811c2fd in std::vector<char, std::allocator<char>>::vector(unsigned long, char const&, std::allocator<char> const&) /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_vector.h:571:9
#7 0x7fcc5811c2fd in std::vector<char, std::allocator<char>> wasm::read_file<std::vector<char, std::allocator<char>>>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, wasm::Flags::BinaryOption) /src/binaryen/src/support/file.cpp:75:5
#8 0x7fcc583bdbbb in wasm::ModuleReader::readBinary(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) /src/binaryen/src/wasm/wasm-io.cpp:77:14
#9 0x7fcc583bf68d in wasm::ModuleReader::read(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, wasm::Module&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>) /src/binaryen/src/wasm/wasm-io.cpp:101:5
#10 0x55b42ff0568c in main /src/binaryen/src/tools/wasm-opt.cpp:319:14
#11 0x7fcc5503f1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#12 0x7fcc5503f28a in __libc_start_main csu/../csu/libc-start.c:360:3
#13 0x55b42fb7a164 in _start (/src/binaryen/build/bin/wasm-opt+0x7a164) (BuildId: 0854baef848e0e3aca2fa54cd3656fe250c93259)
SUMMARY: AddressSanitizer: heap-buffer-overflow /src/binaryen/src/wasm/wasm-binary.cpp:4736:10 in wasm::WasmBinaryReader::readExpression()
Shadow bytes around the buggy address:
0x512000000180: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x512000000200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x512000000280: 00 00 00 00 00 00 00 00 00 00 00 00 05 fa fa fa
0x512000000300: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x512000000380: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x512000000400: 00 00 00 00 00 00 00 00 00 00[fa]fa fa fa fa fa
0x512000000480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x512000000500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x512000000580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x512000000600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x512000000680: 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
==27855==ABORTING
Metadata
Metadata
Assignees
Labels
No labels