Skip to content

[BUG] A heap-use-after-free in wabt::interp::(anonymous namespace)::BinaryReaderInterp::GetFuncOffset(unsigned int) at src/interp/binary-reader-interp.cc:481:12 #2614

Open
@JJLeo

Description

@JJLeo

Description

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

wabt_crash_5.txt

Credit

Reported by Yifan Zhang, PLL

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions