Skip to content

AddressSanitizer: heap-buffer-overflow when using repeated on bool type #287

@nsurbay

Description

@nsurbay

I try to used libprotobuf-mutator, but ASAN raise an error during LLVMFuzzerCustomCrossOver or LLVMFuzzerCustomMutator, so outside of my harness. By looking at the stacktrace, this occurs when handle a field repeated bool. Below a minimal example to reproduce the issue.

I'm not sure if this is an issue with libprotobuf-mutator, or with protobuf.

Files to reproduce

CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(TestLibProtoBuff)

find_package(protobuf REQUIRED)
find_package(libprotobuf-mutator REQUIRED)

add_executable(fuzztarget
  target.cpp
  target.proto
)

protobuf_generate(
  TARGET fuzztarget
  LANGUAGE cpp 
  IMPORT_DIRS "${CMAKE_CURRENT_SOURCE_DIR}"
)

target_include_directories(fuzztarget PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_compile_options(fuzztarget PRIVATE
  -Wall
  -fsanitize=undefined,address,fuzzer-no-link)

target_link_options(fuzztarget PRIVATE
  -fsanitize=undefined,address,fuzzer-no-link
  -fsanitize=fuzzer)

target_link_libraries(fuzztarget
  protobuf::libprotobuf
  libprotobuf-mutator::protobuf-mutator
  libprotobuf-mutator::protobuf-mutator-libfuzzer
)
target.proto
syntax = "proto3";

package Test;

message TargetMessage {
  repeated bool mylist = 1;
}
target.cpp
#include <libfuzzer/libfuzzer_macro.h>
#include "target.pb.h"

DEFINE_PROTO_FUZZER(const Test::TargetMessage& input) {
  // do nothing
  (void) input;
}

Error messages

error within LLVMFuzzerCustomCrossOver
=================================================================
==1507714==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7b1d165ea1bb at pc 0x55f037ef18e6 bp 0x7ffe5934aeb0 sp 0x7ffe5934a670
READ of size 8 at 0x7b1d165ea1bb thread T0
    #0 0x55f037ef18e5 in __asan_memcpy (/tmp/test_protobuf/build/fuzztarget+0x1ae8e5) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #1 0x55f037f59284 in google::protobuf::RepeatedField<bool>::GrowNoAnnotate(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x216284) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #2 0x55f037f5602e in google::protobuf::RepeatedField<bool>::Grow(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x21302e) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #3 0x55f037f88552 in void google::protobuf::Reflection::AddField<bool>(google::protobuf::Message*, google::protobuf::FieldDescriptor const*, bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x245552) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #4 0x55f037f75976 in google::protobuf::Reflection::AddBool(google::protobuf::Message*, google::protobuf::FieldDescriptor const*, bool) const (/tmp/test_protobuf/build/fuzztarget+0x232976) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #5 0x55f0380a917d in protobuf_mutator::FieldInstance::PushBackRepeated(bool) const (/tmp/test_protobuf/build/fuzztarget+0x36617d) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #6 0x55f0380a9037 in void protobuf_mutator::FieldInstance::InsertRepeated<bool>(bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x366037) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #7 0x55f0380a8f33 in void protobuf_mutator::FieldInstance::Create<bool>(bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x365f33) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #8 0x55f0380a12ca in void protobuf_mutator::(anonymous namespace)::CreateDefaultField::ForType<bool>(protobuf_mutator::FieldInstance const&) const mutator.cc
    #9 0x55f03809e605 in void protobuf_mutator::FieldFunction<protobuf_mutator::(anonymous namespace)::CreateDefaultField, void>::operator()<protobuf_mutator::FieldInstance>(protobuf_mutator::FieldInstance const&) const mutator.cc
    #10 0x55f03809d779 in protobuf_mutator::Mutator::MutateImpl(std::vector<google::protobuf::Message const*, std::allocator<google::protobuf::Message const*>> const&, std::vector<google::protobuf::Message*, std::allocator<google::protobuf::Message*>> const&, bool, int) (/tmp/test_protobuf/build/fuzztarget+0x35a779) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #11 0x55f03809dd18 in protobuf_mutator::Mutator::CrossOver(google::protobuf::Message const&, google::protobuf::Message*, unsigned long) (/tmp/test_protobuf/build/fuzztarget+0x35ad18) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #12 0x55f038098af8 in protobuf_mutator::libfuzzer::(anonymous namespace)::CrossOverMessages(unsigned int, protobuf_mutator::libfuzzer::(anonymous namespace)::InputReader const&, protobuf_mutator::libfuzzer::(anonymous namespace)::InputReader const&, protobuf_mutator::libfuzzer::(anonymous namespace)::OutputWriter*, google::protobuf::Message*, google::protobuf::Message*) libfuzzer_macro.cc
    #13 0x55f038098007 in protobuf_mutator::libfuzzer::(anonymous namespace)::CrossOverTextMessages(unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int, google::protobuf::Message*, google::protobuf::Message*) libfuzzer_macro.cc
    #14 0x55f038097e55 in protobuf_mutator::libfuzzer::CustomProtoCrossOver(bool, unsigned char const*, unsigned long, unsigned char const*, unsigned long, unsigned char*, unsigned long, unsigned int, google::protobuf::Message*, google::protobuf::Message*) (/tmp/test_protobuf/build/fuzztarget+0x354e55) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #15 0x55f037f48f34 in LLVMFuzzerCustomCrossOver (/tmp/test_protobuf/build/fuzztarget+0x205f34) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #16 0x55f037deb865 in fuzzer::MutationDispatcher::Mutate_CustomCrossOver(unsigned char*, unsigned long, unsigned long) (/tmp/test_protobuf/build/fuzztarget+0xa8865) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #17 0x55f037deb320 in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator>>&) (/tmp/test_protobuf/build/fuzztarget+0xa8320) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #18 0x55f037dd354f in fuzzer::Fuzzer::MutateAndTestOne() (/tmp/test_protobuf/build/fuzztarget+0x9054f) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #19 0x55f037dd4a27 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/tmp/test_protobuf/build/fuzztarget+0x91a27) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #20 0x55f037db5d58 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/tmp/test_protobuf/build/fuzztarget+0x72d58) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #21 0x55f037d9e417 in main (/tmp/test_protobuf/build/fuzztarget+0x5b417) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #22 0x7efd17227674 in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #23 0x7efd17227728 in __libc_start_main /usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:360:3
    #24 0x55f037d9e594 in _start (/tmp/test_protobuf/build/fuzztarget+0x5b594) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)

0x7b1d165ea1c0 is located 0 bytes after 16-byte region [0x7b1d165ea1b0,0x7b1d165ea1c0)
allocated by thread T0 here:
    #0 0x55f037f45c4d in operator new(unsigned long) (/tmp/test_protobuf/build/fuzztarget+0x202c4d) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #1 0x55f037f5a639 in google::protobuf::internal::AllocateAtLeast(unsigned long) (/tmp/test_protobuf/build/fuzztarget+0x217639) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #2 0x55f037f58d18 in google::protobuf::RepeatedField<bool>::GrowNoAnnotate(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x215d18) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #3 0x55f037f5602e in google::protobuf::RepeatedField<bool>::Grow(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x21302e) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #4 0x55f037f88552 in void google::protobuf::Reflection::AddField<bool>(google::protobuf::Message*, google::protobuf::FieldDescriptor const*, bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x245552) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/tmp/test_protobuf/build/fuzztarget+0x1ae8e5) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428) in __asan_memcpy
Shadow bytes around the buggy address:
  0x7b1d165e9f00: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fa
  0x7b1d165e9f80: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
  0x7b1d165ea000: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
  0x7b1d165ea080: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
  0x7b1d165ea100: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x7b1d165ea180: fa fa fd fa fa fa 00[03]fa fa 00 fa fa fa 00 00
  0x7b1d165ea200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1d165ea280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1d165ea300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1d165ea380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b1d165ea400: 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
==1507714==ABORTING
MS: 0 ; base unit: 08f47a00dba1880d8c4d919b2dbc3f41288686d0


artifact_prefix='./'; Test unit written to ./crash-da39a3ee5e6b4b0d3255bfef95601890afd80709
Base64:
error within LLVMFuzzerCustomMutator
=================================================================
==1542352==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7b3596fec11b at pc 0x55f020acd8e6 bp 0x7ffe5f9e1050 sp 0x7ffe5f9e0810
READ of size 8 at 0x7b3596fec11b thread T0
    #0 0x55f020acd8e5 in __asan_memcpy (/tmp/test_protobuf/build/fuzztarget+0x1ae8e5) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #1 0x55f020b35284 in google::protobuf::RepeatedField<bool>::GrowNoAnnotate(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x216284) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #2 0x55f020b3202e in google::protobuf::RepeatedField<bool>::Grow(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x21302e) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #3 0x55f020b64552 in void google::protobuf::Reflection::AddField<bool>(google::protobuf::Message*, google::protobuf::FieldDescriptor const*, bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x245552) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #4 0x55f020b51976 in google::protobuf::Reflection::AddBool(google::protobuf::Message*, google::protobuf::FieldDescriptor const*, bool) const (/tmp/test_protobuf/build/fuzztarget+0x232976) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #5 0x55f020c8517d in protobuf_mutator::FieldInstance::PushBackRepeated(bool) const (/tmp/test_protobuf/build/fuzztarget+0x36617d) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #6 0x55f020c85037 in void protobuf_mutator::FieldInstance::InsertRepeated<bool>(bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x366037) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #7 0x55f020c84f33 in void protobuf_mutator::FieldInstance::Create<bool>(bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x365f33) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #8 0x55f020c7d8d1 in void protobuf_mutator::(anonymous namespace)::CreateField::ForType<bool>(protobuf_mutator::FieldInstance const&, int, std::vector<google::protobuf::Message const*, std::allocator<google::protobuf::Message const*>> const&, protobuf_mutator::Mutator*) const mutator.cc
    #9 0x55f020c7a131 in void protobuf_mutator::FieldFunction<protobuf_mutator::(anonymous namespace)::CreateField, void>::operator()<protobuf_mutator::FieldInstance, int, std::vector<google::protobuf::Message const*, std::allocator<google::protobuf::Message const*>>, protobuf_mutator::Mutator*>(protobuf_mutator::FieldInstance const&, int const&, std::vector<google::protobuf::Message const*, std::allocator<google::protobuf::Message const*>> const&, protobuf_mutator::Mutator* const&) const mutator.cc
    #10 0x55f020c796ed in protobuf_mutator::Mutator::MutateImpl(std::vector<google::protobuf::Message const*, std::allocator<google::protobuf::Message const*>> const&, std::vector<google::protobuf::Message*, std::allocator<google::protobuf::Message*>> const&, bool, int) (/tmp/test_protobuf/build/fuzztarget+0x35a6ed) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #11 0x55f020c79347 in protobuf_mutator::Mutator::Mutate(google::protobuf::Message*, unsigned long) (/tmp/test_protobuf/build/fuzztarget+0x35a347) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #12 0x55f020c7443e in protobuf_mutator::libfuzzer::(anonymous namespace)::MutateMessage(unsigned int, protobuf_mutator::libfuzzer::(anonymous namespace)::InputReader const&, protobuf_mutator::libfuzzer::(anonymous namespace)::OutputWriter*, google::protobuf::Message*) libfuzzer_macro.cc
    #13 0x55f020c73d88 in protobuf_mutator::libfuzzer::(anonymous namespace)::MutateTextMessage(unsigned char*, unsigned long, unsigned long, unsigned int, google::protobuf::Message*) libfuzzer_macro.cc
    #14 0x55f020c73c68 in protobuf_mutator::libfuzzer::CustomProtoMutator(bool, unsigned char*, unsigned long, unsigned long, unsigned int, google::protobuf::Message*) (/tmp/test_protobuf/build/fuzztarget+0x354c68) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #15 0x55f020b24ad5 in LLVMFuzzerCustomMutator (/tmp/test_protobuf/build/fuzztarget+0x205ad5) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #16 0x55f0209c7320 in fuzzer::MutationDispatcher::MutateImpl(unsigned char*, unsigned long, unsigned long, std::vector<fuzzer::MutationDispatcher::Mutator, std::allocator<fuzzer::MutationDispatcher::Mutator>>&) (/tmp/test_protobuf/build/fuzztarget+0xa8320) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #17 0x55f0209af54f in fuzzer::Fuzzer::MutateAndTestOne() (/tmp/test_protobuf/build/fuzztarget+0x9054f) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #18 0x55f0209b0a27 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/tmp/test_protobuf/build/fuzztarget+0x91a27) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #19 0x55f020991d58 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/tmp/test_protobuf/build/fuzztarget+0x72d58) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #20 0x55f02097a417 in main (/tmp/test_protobuf/build/fuzztarget+0x5b417) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #21 0x7f1597c27674 in __libc_start_call_main /usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #22 0x7f1597c27728 in __libc_start_main /usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:360:3
    #23 0x55f02097a594 in _start (/tmp/test_protobuf/build/fuzztarget+0x5b594) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)

0x7b3596fec120 is located 0 bytes after 16-byte region [0x7b3596fec110,0x7b3596fec120)
allocated by thread T0 here:
    #0 0x55f020b21c4d in operator new(unsigned long) (/tmp/test_protobuf/build/fuzztarget+0x202c4d) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #1 0x55f020b36639 in google::protobuf::internal::AllocateAtLeast(unsigned long) (/tmp/test_protobuf/build/fuzztarget+0x217639) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #2 0x55f020b34d18 in google::protobuf::RepeatedField<bool>::GrowNoAnnotate(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x215d18) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #3 0x55f020b3202e in google::protobuf::RepeatedField<bool>::Grow(bool, int, int) (/tmp/test_protobuf/build/fuzztarget+0x21302e) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)
    #4 0x55f020b64552 in void google::protobuf::Reflection::AddField<bool>(google::protobuf::Message*, google::protobuf::FieldDescriptor const*, bool const&) const (/tmp/test_protobuf/build/fuzztarget+0x245552) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/tmp/test_protobuf/build/fuzztarget+0x1ae8e5) (BuildId: 7018bcb842fb7aa3b9867922a1b31c2471677428) in __asan_memcpy
Shadow bytes around the buggy address:
  0x7b3596febe80: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
  0x7b3596febf00: fa fa fd fa fa fa fd fd fa fa fd fa fa fa fd fa
  0x7b3596febf80: fa fa fd fa fa fa fd fa fa fa fd fd fa fa fd fa
  0x7b3596fec000: fa fa fd fd fa fa fd fa fa fa fd fa fa fa fd fd
  0x7b3596fec080: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fa
=>0x7b3596fec100: fa fa 00[03]fa fa 00 fa fa fa 00 fa fa fa fa fa
  0x7b3596fec180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b3596fec200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b3596fec280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b3596fec300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7b3596fec380: 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
==1542352==ABORTING
MS: 0 ; base unit: 7a88237dbf2241315f4ad9e794232e06092e70f1


artifact_prefix='./'; Test unit written to ./crash-da39a3ee5e6b4b0d3255bfef95601890afd80709
Base64:

Software Versions

  • Protobuf : tested with main version and release v32.0
  • libprotobuf-mutator : current master version
  • clang : version 20.1.8

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