Index: llvm/trunk/lib/Fuzzer/FuzzerMutate.h =================================================================== --- llvm/trunk/lib/Fuzzer/FuzzerMutate.h +++ llvm/trunk/lib/Fuzzer/FuzzerMutate.h @@ -143,6 +143,9 @@ 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; Index: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp =================================================================== --- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp +++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp @@ -81,8 +81,8 @@ 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) Index: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt =================================================================== --- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt +++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt @@ -80,6 +80,7 @@ BufferOverflowOnInput CallerCalleeTest CounterTest + CustomCrossOverAndMutateTest CustomCrossOverTest CustomMutatorTest CxxStringEqTest Index: llvm/trunk/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp =================================================================== --- llvm/trunk/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp +++ llvm/trunk/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; +} Index: llvm/trunk/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test =================================================================== --- llvm/trunk/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test +++ llvm/trunk/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test @@ -0,0 +1 @@ +RUN: LLVMFuzzer-CustomCrossOverAndMutateTest -seed=1 -use_memcmp=0 -runs=100000