From: Vitaly Buka Date: Tue, 7 Mar 2017 20:37:38 +0000 (+0000) Subject: [fuzzer] Don't crash if LLVMFuzzerMutate was called by CustomCrossOver X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c3e480920349b91ff80f2bc6961eb0ad971a1110;p=llvm [fuzzer] Don't crash if LLVMFuzzerMutate was called by CustomCrossOver Reviewers: kcc Subscribers: llvm-commits, mgorny Differential Revision: https://reviews.llvm.org/D30682 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@297202 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Fuzzer/FuzzerMutate.cpp b/lib/Fuzzer/FuzzerMutate.cpp index 7c7e6688aa7..c9768e4a5f2 100644 --- a/lib/Fuzzer/FuzzerMutate.cpp +++ b/lib/Fuzzer/FuzzerMutate.cpp @@ -81,8 +81,8 @@ size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size, const Unit &Other = (*Corpus)[Idx]; if (Other.empty()) return 0; - MutateInPlaceHere.resize(MaxSize); - auto &U = MutateInPlaceHere; + CustomCrossOverInPlaceHere.resize(MaxSize); + auto &U = CustomCrossOverInPlaceHere; size_t NewSize = EF->LLVMFuzzerCustomCrossOver( Data, Size, Other.data(), Other.size(), U.data(), U.size(), Rand.Rand()); if (!NewSize) diff --git a/lib/Fuzzer/FuzzerMutate.h b/lib/Fuzzer/FuzzerMutate.h index 3d78b111c66..8c8fb3fd74c 100644 --- a/lib/Fuzzer/FuzzerMutate.h +++ b/lib/Fuzzer/FuzzerMutate.h @@ -143,6 +143,9 @@ private: const InputCorpus *Corpus = nullptr; std::vector MutateInPlaceHere; + // CustomCrossOver needs its own buffer as a custom implementation may call + // LLVMFuzzerMutate, which in turn may resize MutateInPlaceHere. + std::vector CustomCrossOverInPlaceHere; std::vector Mutators; std::vector DefaultMutators; diff --git a/lib/Fuzzer/test/CMakeLists.txt b/lib/Fuzzer/test/CMakeLists.txt index 14d5f12f4e9..ab4ae92c1f4 100644 --- a/lib/Fuzzer/test/CMakeLists.txt +++ b/lib/Fuzzer/test/CMakeLists.txt @@ -80,6 +80,7 @@ set(Tests BufferOverflowOnInput CallerCalleeTest CounterTest + CustomCrossOverAndMutateTest CustomCrossOverTest CustomMutatorTest CxxStringEqTest diff --git a/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp b/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp new file mode 100644 index 00000000000..8aa8fdd050e --- /dev/null +++ b/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp @@ -0,0 +1,33 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Test that libFuzzer does not crash when LLVMFuzzerMutate called from +// LLVMFuzzerCustomCrossOver. +#include +#include +#include +#include +#include +#include + +#include "FuzzerInterface.h" + +static volatile int sink; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + std::string Str(reinterpret_cast(Data), Size); + if (Size && Data[0] == '0') + sink++; + return 0; +} + +extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1, + const uint8_t *Data2, size_t Size2, + uint8_t *Out, size_t MaxOutSize, + unsigned int Seed) { + std::vector Buffer(MaxOutSize * 10); + LLVMFuzzerMutate(Buffer.data(), Buffer.size(), Buffer.size()); + size_t Size = std::min(Size1, MaxOutSize); + memcpy(Out, Data1, Size); + return Size; +} diff --git a/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test b/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test new file mode 100644 index 00000000000..218019d232b --- /dev/null +++ b/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test @@ -0,0 +1 @@ +RUN: LLVMFuzzer-CustomCrossOverAndMutateTest -seed=1 -use_memcmp=0 -runs=100000