Open
Description
Description
- Version: Commit a60eb26
- Environment:Ubuntu 20.04.6 LTS, Clang 18.1.8
- Fuzzing harness: https://github.com/google/oss-fuzz/raw/refs/heads/master/projects/wabt/read_binary_interp_fuzzer.cc
Please let me know if you encounter any issues reproducing it — I can upload a Docker image to help.
Steps to reproduce
export CC="clang"
export CXX="clang++"
export CFLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer"
export CXXFLAGS="-fsanitize=address -g -O0 -fno-omit-frame-pointer -stdlib=libc++"
export LIB_FUZZING_ENGINE="-fsanitize=fuzzer"
mkdir build
cd build
cmake .. -DBUILD_TESTS=OFF
cmake --build . --parallel
cd ..
wget https://github.com/google/oss-fuzz/raw/refs/heads/master/projects/wabt/read_binary_interp_fuzzer.cc
$CXX $CXXFLAGS -std=c++17 -I. -Ibuild -Iinclude -Ibuild/include \
./src/read_binary_interp_fuzzer.cc $LIB_FUZZING_ENGINE ./build/libwabt.a \
-o ./read_binary_interp_fuzzer
wget https://github.com/user-attachments/files/20623626/wabt_crash_5.txt
./read_binary_interp_fuzzer wasm_crash_5.txt
Sanitizer output
==410394==ERROR: AddressSanitizer: heap-use-after-free on address 0x6110000002c8 at pc 0x0000004b1196 bp 0x7ffc1d1fdbb0 sp 0x7ffc1d1fdba8
READ of size 4 at 0x6110000002c8 thread T0
#0 0x4b1195 in wabt::interp::(anonymous namespace)::BinaryReaderInterp::GetFuncOffset(unsigned int) /src/wabt/src/interp/binary-reader-interp.cc:481:12
#1 0x4b1195 in wabt::interp::(anonymous namespace)::BinaryReaderInterp::OnReturnCallExpr(unsigned int) /src/wabt/src/interp/binary-reader-interp.cc:1200:19
#2 0x935161 in wabt::(anonymous namespace)::BinaryReader::ReadInstructions(unsigned long, char const*) /src/wabt/src/binary-reader.cc:965:9
#3 0x8dd385 in wabt::(anonymous namespace)::BinaryReader::ReadFunctionBody(unsigned long) /src/wabt/src/binary-reader.cc:714:3
#4 0x8dd385 in wabt::(anonymous namespace)::BinaryReader::ReadCodeSection(unsigned long) /src/wabt/src/binary-reader.cc:2892:7
#5 0x8dd385 in wabt::(anonymous namespace)::BinaryReader::ReadSections(wabt::(anonymous namespace)::BinaryReader::ReadSectionsOptions const&) /src/wabt/src/binary-reader.cc:3045:26
#6 0x8bb810 in wabt::(anonymous namespace)::BinaryReader::ReadModule(wabt::(anonymous namespace)::BinaryReader::ReadModuleOptions const&) /src/wabt/src/binary-reader.cc:3119:3
#7 0x8bb810 in wabt::ReadBinary(void const*, unsigned long, wabt::BinaryReaderDelegate*, wabt::ReadBinaryOptions const&) /src/wabt/src/binary-reader.cc:3141:17
#8 0x523f97 in wabt::interp::ReadBinaryInterp(std::__1::basic_string_view<char, std::__1::char_traits<char> >, void const*, unsigned long, wabt::ReadBinaryOptions const&, std::__1::vector<wabt::Error, std::__1::allocator<wabt::Error> >*, wabt::interp::ModuleDesc*) /src/wabt/src/interp/binary-reader-interp.cc:1742:10
#9 0x40f28f in LLVMFuzzerTestOneInput /src/read_binary_interp_fuzzer.cc:39:3
#10 0xadd54a in main (/out/read_binary_interp_fuzzer.fuzz+0xadd54a)
#11 0x7f1f09428082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082)
#12 0x40980d in _start (/out/read_binary_interp_fuzzer.fuzz+0x40980d)
0x6110000002c8 is located 8 bytes inside of 256-byte region [0x6110000002c0,0x6110000003c0)
freed by thread T0 here:
#0 0xb4dc12 in free (/out/read_binary_interp_fuzzer.fuzz+0xb4dc12)
#1 0x44493e in void std::__1::__libcpp_operator_delete<void*>(void*) /usr/lib/llvm-12/bin/../include/c++/v1/new:245:3
#2 0x44493e in void std::__1::__do_deallocate_handle_size<>(void*, unsigned long) /usr/lib/llvm-12/bin/../include/c++/v1/new:269:10
#3 0x44493e in std::__1::__libcpp_deallocate(void*, unsigned long, unsigned long) /usr/lib/llvm-12/bin/../include/c++/v1/new:285:14
#4 0x44493e in std::__1::allocator<wabt::Error>::deallocate(wabt::Error*, unsigned long) /usr/lib/llvm-12/bin/../include/c++/v1/memory:874:13
#5 0x44493e in std::__1::allocator_traits<std::__1::allocator<wabt::Error> >::deallocate(std::__1::allocator<wabt::Error>&, wabt::Error*, unsigned long) /usr/lib/llvm-12/bin/../include/c++/v1/__memory/allocator_traits.h:280:13
#6 0x44493e in std::__1::__split_buffer<wabt::Error, std::__1::allocator<wabt::Error>&>::~__split_buffer() /usr/lib/llvm-12/bin/../include/c++/v1/__split_buffer:346:9
#7 0x44493e in void std::__1::vector<wabt::Error, std::__1::allocator<wabt::Error> >::__push_back_slow_path<wabt::Error const&>(wabt::Error const&) /usr/lib/llvm-12/bin/../include/c++/v1/vector:1629:1
#8 0x44493e in std::__1::vector<wabt::Error, std::__1::allocator<wabt::Error> >::push_back(wabt::Error const&) /usr/lib/llvm-12/bin/../include/c++/v1/vector:1641:9
#9 0x44493e in wabt::interp::(anonymous namespace)::BinaryReaderInterp::OnError(wabt::Error const&) /src/wabt/src/interp/binary-reader-interp.cc:488:12
#10 0x8beafb in wabt::(anonymous namespace)::BinaryReader::PrintError(char const*, ...) /src/wabt/src/binary-reader.cc:242:29
#11 0x8c109c in wabt::(anonymous namespace)::BinaryReader::ReadSections(wabt::(anonymous namespace)::BinaryReader::ReadSectionsOptions const&) /src/wabt/src/binary-reader.cc:2959:7
#12 0x8bb810 in wabt::(anonymous namespace)::BinaryReader::ReadModule(wabt::(anonymous namespace)::BinaryReader::ReadModuleOptions const&) /src/wabt/src/binary-reader.cc:3119:3
#13 0x8bb810 in wabt::ReadBinary(void const*, unsigned long, wabt::BinaryReaderDelegate*, wabt::ReadBinaryOptions const&) /src/wabt/src/binary-reader.cc:3141:17
#14 0x523f97 in wabt::interp::ReadBinaryInterp(std::__1::basic_string_view<char, std::__1::char_traits<char> >, void const*, unsigned long, wabt::ReadBinaryOptions const&, std::__1::vector<wabt::Error, std::__1::allocator<wabt::Error> >*, wabt::interp::ModuleDesc*) /src/wabt/src/interp/binary-reader-interp.cc:1742:10
#15 0x40f28f in LLVMFuzzerTestOneInput /src/read_binary_interp_fuzzer.cc:39:3
#16 0xadd54a in main (/out/read_binary_interp_fuzzer.fuzz+0xadd54a)
previously allocated by thread T0 here:
#0 0xb4de7d in malloc (/out/read_binary_interp_fuzzer.fuzz+0xb4de7d)
#1 0x7f1f09b60b28 in operator new(unsigned long) (/lib/x86_64-linux-gnu/libstdc++.so.6+0xaab28)
#2 0x98457f in wabt::Error& std::__1::vector<wabt::Error, std::__1::allocator<wabt::Error> >::emplace_back<wabt::ErrorLevel, wabt::Location const&, char*&>(wabt::ErrorLevel&&, wabt::Location const&, char*&) /usr/lib/llvm-12/bin/../include/c++/v1/vector:1687:9
#3 0x98457f in wabt::SharedValidator::PrintError(wabt::Location const&, char const*, ...) /src/wabt/src/shared-validator.cc:39:12
#4 0x98d7d9 in wabt::SharedValidator::CheckIndex(wabt::Var, unsigned int, char const*) /src/wabt/src/shared-validator.cc:328:12
#5 0x98d7d9 in wabt::SharedValidator::CheckFuncTypeIndex(wabt::Var, wabt::SharedValidator::FuncType*) /src/wabt/src/shared-validator.cc:361:19
#6 0x98beb6 in wabt::SharedValidator::OnFunction(wabt::Location const&, wabt::Var) /src/wabt/src/shared-validator.cc:82:13
#7 0x45bade in wabt::interp::(anonymous namespace)::BinaryReaderInterp::OnFunction(unsigned int, unsigned int) /src/wabt/src/interp/binary-reader-interp.cc:590:3
#8 0x8ceeaf in wabt::(anonymous namespace)::BinaryReader::ReadFunctionSection(unsigned long) /src/wabt/src/binary-reader.cc:2701:5
#9 0x8ceeaf in wabt::(anonymous namespace)::BinaryReader::ReadSections(wabt::(anonymous namespace)::BinaryReader::ReadSectionsOptions const&) /src/wabt/src/binary-reader.cc:3017:26
#10 0x8bb810 in wabt::(anonymous namespace)::BinaryReader::ReadModule(wabt::(anonymous namespace)::BinaryReader::ReadModuleOptions const&) /src/wabt/src/binary-reader.cc:3119:3
#11 0x8bb810 in wabt::ReadBinary(void const*, unsigned long, wabt::BinaryReaderDelegate*, wabt::ReadBinaryOptions const&) /src/wabt/src/binary-reader.cc:3141:17
#12 0x523f97 in wabt::interp::ReadBinaryInterp(std::__1::basic_string_view<char, std::__1::char_traits<char> >, void const*, unsigned long, wabt::ReadBinaryOptions const&, std::__1::vector<wabt::Error, std::__1::allocator<wabt::Error> >*, wabt::interp::ModuleDesc*) /src/wabt/src/interp/binary-reader-interp.cc:1742:10
#13 0x40f28f in LLVMFuzzerTestOneInput /src/read_binary_interp_fuzzer.cc:39:3
#14 0xadd54a in main (/out/read_binary_interp_fuzzer.fuzz+0xadd54a)
SUMMARY: AddressSanitizer: heap-use-after-free /src/wabt/src/interp/binary-reader-interp.cc:481:12 in wabt::interp::(anonymous namespace)::BinaryReaderInterp::GetFuncOffset(unsigned int)
Shadow bytes around the buggy address:
0x0c227fff8000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
0x0c227fff8010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fff8020: 00 00 00 00 00 00 fa fa fa fa fa fa fa fa fa fa
0x0c227fff8030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc
0x0c227fff8040: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fa fa
=>0x0c227fff8050: fa fa fa fa fa fa fa fa fd[fd]fd fd fd fd fd fd
0x0c227fff8060: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c227fff8070: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
0x0c227fff8080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c227fff8090: 00 00 00 00 00 fc fc fc fc fc fc fc fa fa fa fa
0x0c227fff80a0: 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
Shadow gap: cc
==410394==ABORTING
POC
Credit
Reported by Yifan Zhang, PLL
Metadata
Metadata
Assignees
Labels
No labels