[llvm] r238059 - [lib/Fuzzer] extend the fuzzer interface to allow user-supplied mutators
Kostya Serebryany
kcc at google.com
Fri May 22 19:15:56 PDT 2015
Attempted in r238086.
On Fri, May 22, 2015 at 4:16 PM, Justin Bogner <mail at justinbogner.com>
wrote:
> Kostya Serebryany <kcc at google.com> writes:
> > Author: kcc
> > Date: Fri May 22 17:35:31 2015
> > New Revision: 238059
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=238059&view=rev
> > Log:
> > [lib/Fuzzer] extend the fuzzer interface to allow user-supplied mutators
> >
> > Added:
> > llvm/trunk/lib/Fuzzer/FuzzerInterface.cpp
> > llvm/trunk/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp
> > Modified:
> > llvm/trunk/lib/Fuzzer/CMakeLists.txt
> > llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp
> > llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
> > llvm/trunk/lib/Fuzzer/FuzzerInterface.h
> > llvm/trunk/lib/Fuzzer/FuzzerInternal.h
> > llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
> > llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
> > llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
> > llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
> > llvm/trunk/lib/Fuzzer/test/fuzzer.test
> >
> > Modified: llvm/trunk/lib/Fuzzer/CMakeLists.txt
> > URL:
> >
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/CMakeLists.txt?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/Fuzzer/CMakeLists.txt Fri May 22 17:35:31 2015
> > @@ -2,8 +2,9 @@ set(LIBFUZZER_FLAGS_BASE "${CMAKE_CXX_FL
> > # Disable the coverage and sanitizer instrumentation for the fuzzer
> itself.
> > set(CMAKE_CXX_FLAGS_RELEASE "${LIBFUZZER_FLAGS_BASE} -O2
> -fno-sanitize=all")
> > if( LLVM_USE_SANITIZE_COVERAGE )
> > - add_library(LLVMFuzzerNoMain OBJECT
> > + add_library(LLVMFuzzerNoMainObjects OBJECT
> > FuzzerCrossOver.cpp
> > + FuzzerInterface.cpp
> > FuzzerTraceState.cpp
> > FuzzerDriver.cpp
> > FuzzerIO.cpp
> > @@ -13,9 +14,12 @@ if( LLVM_USE_SANITIZE_COVERAGE )
> > FuzzerSHA1.cpp
> > FuzzerUtil.cpp
> > )
> > + add_library(LLVMFuzzerNoMain STATIC
> > + $<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>
> > + )
> > add_library(LLVMFuzzer STATIC
> > FuzzerMain.cpp
> > - $<TARGET_OBJECTS:LLVMFuzzerNoMain>
> > + $<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>
> > )
> >
> > if( LLVM_INCLUDE_TESTS )
> >
> > Modified: llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp (original)
> > +++ llvm/trunk/lib/Fuzzer/FuzzerCrossOver.cpp Fri May 22 17:35:31 2015
> > @@ -9,39 +9,42 @@
> > // Cross over test inputs.
> >
> //===----------------------------------------------------------------------===//
> >
> > +#include <cstring>
> > +
> > #include "FuzzerInternal.h"
> > -#include <algorithm>
> >
> > namespace fuzzer {
> >
> > -// Cross A and B, store the result (ap to MaxLen bytes) in U.
> > -void CrossOver(const Unit &A, const Unit &B, Unit *U, size_t MaxLen) {
> > - size_t Size = rand() % MaxLen + 1;
> > - U->clear();
> > - const Unit *V = &A;
> > - size_t PosA = 0;
> > - size_t PosB = 0;
> > - size_t *Pos = &PosA;
> > - while (U->size() < Size && (PosA < A.size() || PosB < B.size())) {
> > - // Merge a part of V into U.
> > - size_t SizeLeftU = Size - U->size();
> > - if (*Pos < V->size()) {
> > - size_t SizeLeftV = V->size() - *Pos;
> > - size_t MaxExtraSize = std::min(SizeLeftU, SizeLeftV);
> > +// Cross Data1 and Data2, store the result (up to MaxOutSize bytes) in
> Out.
> > +size_t CrossOver(const uint8_t *Data1, size_t Size1,
> > + const uint8_t *Data2, size_t Size2,
> > + uint8_t *Out, size_t MaxOutSize) {
> > + MaxOutSize = rand() % MaxOutSize + 1;
> > + size_t OutPos = 0;
> > + size_t Pos1 = 0;
> > + size_t Pos2 = 0;
> > + size_t *InPos = &Pos1;
> > + size_t InSize = Size1;
> > + const uint8_t *Data = Data1;
> > + bool CurrentlyUsingFirstData = true;
> > + while (OutPos < MaxOutSize && (Pos1 < Size1 || Pos2 < Size2)) {
> > + // Merge a part of Data into Out.
> > + size_t OutSizeLeft = MaxOutSize - OutPos;
> > + if (*InPos < InSize) {
> > + size_t InSizeLeft = InSize - *InPos;
> > + size_t MaxExtraSize = std::min(OutSizeLeft, InSizeLeft);
> > size_t ExtraSize = rand() % MaxExtraSize + 1;
> > - U->insert(U->end(), V->begin() + *Pos, V->begin() + *Pos +
> ExtraSize);
> > - (*Pos) += ExtraSize;
> > - }
> > -
> > - // Use the other Unit on the next iteration.
> > - if (Pos == &PosA) {
> > - Pos = &PosB;
> > - V = &B;
> > - } else {
> > - Pos = &PosA;
> > - V = &A;
> > + memcpy(Out + OutPos, Data + *InPos, ExtraSize);
> > + OutPos += ExtraSize;
> > + (*InPos) += ExtraSize;
> > }
> > + // Use the other input data on the next iteration.
> > + InPos = CurrentlyUsingFirstData ? &Pos2 : &Pos1;
> > + InSize = CurrentlyUsingFirstData ? Size2 : Size1;
> > + Data = CurrentlyUsingFirstData ? Data2 : Data1;
> > + CurrentlyUsingFirstData = !CurrentlyUsingFirstData;
> > }
> > + return OutPos;
> > }
> >
> > } // namespace fuzzer
> >
> > Modified: llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp (original)
> > +++ llvm/trunk/lib/Fuzzer/FuzzerDriver.cpp Fri May 22 17:35:31 2015
> > @@ -204,6 +204,11 @@ int ApplyTokens(const Fuzzer &F, const c
> > }
> >
> > int FuzzerDriver(int argc, char **argv, UserCallback Callback) {
> > + SimpleUserSuppliedFuzzer SUSF(Callback);
> > + return FuzzerDriver(argc, argv, SUSF);
> > +}
> > +
> > +int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF) {
> > using namespace fuzzer;
> >
> > ProgName = argv[0];
> > @@ -244,7 +249,7 @@ int FuzzerDriver(int argc, char **argv,
> > if (Flags.sync_command)
> > Options.SyncCommand = Flags.sync_command;
> > Options.SyncTimeout = Flags.sync_timeout;
> > - Fuzzer F(Callback, Options);
> > + Fuzzer F(USF, Options);
> >
> > unsigned seed = Flags.seed;
> > // Initialize seed.
> >
> > Added: llvm/trunk/lib/Fuzzer/FuzzerInterface.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInterface.cpp?rev=238059&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/FuzzerInterface.cpp (added)
> > +++ llvm/trunk/lib/Fuzzer/FuzzerInterface.cpp Fri May 22 17:35:31 2015
> > @@ -0,0 +1,27 @@
> > +//===- FuzzerInterface.cpp - Mutate a test input
> --------------------------===//
> > +//
> > +// The LLVM Compiler Infrastructure
> > +//
> > +// This file is distributed under the University of Illinois Open Source
> > +// License. See LICENSE.TXT for details.
> > +//
> >
> +//===----------------------------------------------------------------------===//
> > +// Parts of public interface for libFuzzer.
> >
> +//===----------------------------------------------------------------------===//
> > +
> > +
> > +#include "FuzzerInterface.h"
> > +#include "FuzzerInternal.h"
> > +
> > +namespace fuzzer {
> > +size_t UserSuppliedFuzzer::BasicMutate(uint8_t *Data, size_t Size,
> > + size_t MaxSize) {
> > + return ::fuzzer::Mutate(Data, Size, MaxSize);
> > +}
> > +size_t UserSuppliedFuzzer::BasicCrossOver(const uint8_t *Data1, size_t
> Size1,
> > + const uint8_t *Data2, size_t
> Size2,
> > + uint8_t *Out, size_t
> MaxOutSize) {
> > + return ::fuzzer::CrossOver(Data1, Size1, Data2, Size2, Out,
> MaxOutSize);
> > +}
> > +
> > +} // namespace fuzzer.
> >
> > Modified: llvm/trunk/lib/Fuzzer/FuzzerInterface.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInterface.h?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/FuzzerInterface.h (original)
> > +++ llvm/trunk/lib/Fuzzer/FuzzerInterface.h Fri May 22 17:35:31 2015
> > @@ -9,6 +9,10 @@
> > // Define the interface between the Fuzzer and the library being tested.
> >
> //===----------------------------------------------------------------------===//
> >
> > +// WARNING: keep the interface free of STL or any other header-based
> C++ lib,
> > +// to avoid bad interactions between the code used in the fuzzer and
> > +// the code used in the target function.
> > +
> > #ifndef LLVM_FUZZER_INTERFACE_H
> > #define LLVM_FUZZER_INTERFACE_H
> >
> > @@ -17,9 +21,69 @@
> >
> > namespace fuzzer {
> >
> > -typedef void (*UserCallback)(const uint8_t *data, size_t size);
> > +// Simple C-like interface with a single user-supplied callback.
> > +/* Usage:
> ---------------------------------------------------------------------
> > +#include "FuzzerInterface.h"
> > +
> > +void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
> > + DoStuffWithData(Data, Size);
> > +}
> > +
> > +// Implement your own main() or use the one from FuzzerMain.cpp.
> > +int main(int argc, char **argv) {
> > + InitializeMeIfNeeded();
> > + return fuzzer::FuzzerDriver(argc, argv, LLVMFuzzerTestOneInput);
> > +}
> >
> +-----------------------------------------------------------------------------
> */
> > +typedef void (*UserCallback)(const uint8_t *Data, size_t Size);
> > int FuzzerDriver(int argc, char **argv, UserCallback Callback);
> >
> > +// An abstract class that allows to use user-supplied mutators with
> libFuzzer.
> > +/* Usage:
> ---------------------------------------------------------------------
> > +#include "FuzzerInterface.h"
> > +class MyFuzzer : public fuzzer::UserSuppliedFuzzer {
> > + public:
> > + // Must define the target function.
> > + void TargetFunction(...) { ... }
> > + // Optionally define the mutator.
> > + size_t Mutate(...) { ... }
> > + // Optionally define the CrossOver method.
> > + size_t CrossOver(...) { ... }
> > +};
> > +
> > +int main(int argc, char **argv) {
> > + MyFuzzer F;
> > + fuzzer::FuzzerDriver(argc, argv, F);
> > +}
> >
> +-----------------------------------------------------------------------------
> > */
>
> Please use doxygen comments (///) for these, so the examples show up on
> llvm.org/doxygen.
>
> > +class UserSuppliedFuzzer {
> > + public:
> > + // Executes the target function on 'Size' bytes of 'Data'.
> > + virtual void TargetFunction(const uint8_t *Data, size_t Size) = 0;
> > + // Mutates 'Size' bytes of data in 'Data' inplace into up to
> 'MaxSize' bytes,
> > + // returns the new size of the data.
> > + virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
> > + return BasicMutate(Data, Size, MaxSize);
> > + }
> > + // Crosses 'Data1' and 'Data2', writes up to 'MaxOutSize' bytes into
> Out,
> > + // returns the number of bytes written.
> > + virtual size_t CrossOver(const uint8_t *Data1, size_t Size1,
> > + const uint8_t *Data2, size_t Size2,
> > + uint8_t *Out, size_t MaxOutSize) {
> > + return BasicCrossOver(Data1, Size1, Data2, Size2, Out, MaxOutSize);
> > + }
> > + virtual ~UserSuppliedFuzzer() {}
> > +
> > + protected:
> > + // These can be called internally by Mutate and CrossOver.
> > + size_t BasicMutate(uint8_t *Data, size_t Size, size_t MaxSize);
> > + size_t BasicCrossOver(const uint8_t *Data1, size_t Size1,
> > + const uint8_t *Data2, size_t Size2,
> > + uint8_t *Out, size_t MaxOutSize);
> > +};
> > +
> > +int FuzzerDriver(int argc, char **argv, UserSuppliedFuzzer &USF);
> > +
> > } // namespace fuzzer
> >
> > #endif // LLVM_FUZZER_INTERFACE_H
> >
> > Modified: llvm/trunk/lib/Fuzzer/FuzzerInternal.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerInternal.h?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/FuzzerInternal.h (original)
> > +++ llvm/trunk/lib/Fuzzer/FuzzerInternal.h Fri May 22 17:35:31 2015
> > @@ -33,9 +33,10 @@ void CopyFileToErr(const std::string &Pa
> > std::string DirPlusFile(const std::string &DirPath,
> > const std::string &FileName);
> >
> > -void Mutate(Unit *U, size_t MaxLen);
> > +size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize);
> >
> > -void CrossOver(const Unit &A, const Unit &B, Unit *U, size_t MaxLen);
> > +size_t CrossOver(const uint8_t *Data1, size_t Size1, const uint8_t
> *Data2,
> > + size_t Size2, uint8_t *Out, size_t MaxOutSize);
> >
> > void Print(const Unit &U, const char *PrintAfter = "");
> > void PrintASCII(const Unit &U, const char *PrintAfter = "");
> > @@ -72,7 +73,7 @@ class Fuzzer {
> > std::string SyncCommand;
> > std::vector<std::string> Tokens;
> > };
> > - Fuzzer(UserCallback Callback, FuzzingOptions Options);
> > + Fuzzer(UserSuppliedFuzzer &USF, FuzzingOptions Options);
> > void AddToCorpus(const Unit &U) { Corpus.push_back(U); }
> > void Loop(size_t NumIterations);
> > void ShuffleAndMinimize();
> > @@ -144,7 +145,7 @@ class Fuzzer {
> > return Res;
> > }
> >
> > - UserCallback Callback;
> > + UserSuppliedFuzzer &USF;
> > FuzzingOptions Options;
> > system_clock::time_point ProcessStartTime = system_clock::now();
> > system_clock::time_point LastExternalSync = system_clock::now();
> > @@ -153,4 +154,15 @@ class Fuzzer {
> > long EpochOfLastReadOfOutputCorpus = 0;
> > };
> >
> > +class SimpleUserSuppliedFuzzer: public UserSuppliedFuzzer {
> > + public:
> > + SimpleUserSuppliedFuzzer(UserCallback Callback) : Callback(Callback)
> {}
> > + virtual void TargetFunction(const uint8_t *Data, size_t Size) {
> > + return Callback(Data, Size);
> > + }
> > +
> > + private:
> > + UserCallback Callback;
> > +};
> > +
> > }; // namespace fuzzer
> >
> > Modified: llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp (original)
> > +++ llvm/trunk/lib/Fuzzer/FuzzerLoop.cpp Fri May 22 17:35:31 2015
> > @@ -19,8 +19,8 @@ namespace fuzzer {
> > // Only one Fuzzer per process.
> > static Fuzzer *F;
> >
> > -Fuzzer::Fuzzer(UserCallback Callback, FuzzingOptions Options)
> > - : Callback(Callback), Options(Options) {
> > +Fuzzer::Fuzzer(UserSuppliedFuzzer &USF, FuzzingOptions Options)
> > + : USF(USF), Options(Options) {
> > SetDeathCallback();
> > InitializeTraceState();
> > assert(!F);
> > @@ -207,10 +207,10 @@ Unit Fuzzer::SubstituteTokens(const Unit
> >
> > void Fuzzer::ExecuteCallback(const Unit &U) {
> > if (Options.Tokens.empty()) {
> > - Callback(U.data(), U.size());
> > + USF.TargetFunction(U.data(), U.size());
> > } else {
> > auto T = SubstituteTokens(U);
> > - Callback(T.data(), T.size());
> > + USF.TargetFunction(T.data(), T.size());
> > }
> > }
> >
> > @@ -321,7 +321,11 @@ void Fuzzer::ReportNewCoverage(size_t Ne
> > void Fuzzer::MutateAndTestOne(Unit *U) {
> > for (int i = 0; i < Options.MutateDepth; i++) {
> > StartTraceRecording();
> > - Mutate(U, Options.MaxLen);
> > + size_t Size = U->size();
> > + U->resize(Options.MaxLen);
> > + size_t NewSize = USF.Mutate(U->data(), Size, U->size());
> > + assert(NewSize > 0 && NewSize <= Options.MaxLen);
> > + U->resize(NewSize);
> > RunOneAndUpdateCorpus(*U);
> > size_t NumTraceBasedMutations = StopTraceRecording();
> > for (size_t j = 0; j < NumTraceBasedMutations; j++) {
> > @@ -344,8 +348,12 @@ void Fuzzer::Loop(size_t NumIterations)
> > // Now, cross with others.
> > if (Options.DoCrossOver) {
> > for (size_t J2 = 0; J2 < Corpus.size(); J2++) {
> > - CurrentUnit.clear();
> > - CrossOver(Corpus[J1], Corpus[J2], &CurrentUnit,
> Options.MaxLen);
> > + CurrentUnit.resize(Options.MaxLen);
> > + size_t NewSize = USF.CrossOver(
> > + Corpus[J1].data(), Corpus[J1].size(), Corpus[J2].data(),
> > + Corpus[J2].size(), CurrentUnit.data(),
> CurrentUnit.size());
> > + assert(NewSize > 0 && NewSize <= Options.MaxLen);
> > + CurrentUnit.resize(NewSize);
> > MutateAndTestOne(&CurrentUnit);
> > }
> > }
> >
> > Modified: llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp (original)
> > +++ llvm/trunk/lib/Fuzzer/FuzzerMutate.cpp Fri May 22 17:35:31 2015
> > @@ -9,6 +9,8 @@
> > // Mutate a test input.
> >
> //===----------------------------------------------------------------------===//
> >
> > +#include <cstring>
> > +
> > #include "FuzzerInternal.h"
> >
> > namespace fuzzer {
> > @@ -31,40 +33,39 @@ static char RandCh() {
> > return Special[rand() % (sizeof(Special) - 1)];
> > }
> >
> > -// Mutate U in place.
> > -void Mutate(Unit *U, size_t MaxLen) {
> > - assert(MaxLen > 0);
> > - assert(U->size() <= MaxLen);
> > - if (U->empty()) {
> > - for (size_t i = 0; i < MaxLen; i++)
> > - U->push_back(RandCh());
> > - return;
> > +// Mutates Data in place, returns new size.
> > +size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
> > + assert(MaxSize > 0);
> > + assert(Size <= MaxSize);
> > + if (Size == 0) {
> > + for (size_t i = 0; i < MaxSize; i++)
> > + Data[i] = RandCh();
> > + return MaxSize;
> > }
> > - assert(!U->empty());
> > + assert(Size > 0);
> > + size_t Idx = rand() % Size;
> > switch (rand() % 3) {
> > case 0:
> > - if (U->size() > 1) {
> > - U->erase(U->begin() + rand() % U->size());
> > - break;
> > + if (Size > 1) {
> > + // Erase Data[Idx].
> > + memmove(Data + Idx, Data + Idx + 1, Size - Idx - 1);
> > + Size = Size - 1;
> > }
> > [[clang::fallthrough]];
> > case 1:
> > - if (U->size() < MaxLen) {
> > - U->insert(U->begin() + rand() % U->size(), RandCh());
> > - } else { // At MaxLen.
> > - uint8_t Ch = RandCh();
> > - size_t Idx = rand() % U->size();
> > - (*U)[Idx] = Ch;
> > + if (Size < MaxSize) {
> > + // Insert new value at Data[Idx].
> > + memmove(Data + Idx + 1, Data + Idx, Size - Idx);
> > + Data[Idx] = RandCh();
> > }
> > + Data[Idx] = RandCh();
> > break;
> > - default:
> > - {
> > - size_t Idx = rand() % U->size();
> > - (*U)[Idx] = FlipRandomBit((*U)[Idx]);
> > - }
> > + case 2:
> > + Data[Idx] = FlipRandomBit(Data[Idx]);
> > break;
> > }
> > - assert(!U->empty());
> > + assert(Size > 0);
> > + return Size;
> > }
> >
> > } // namespace fuzzer
> >
> > Modified: llvm/trunk/lib/Fuzzer/test/CMakeLists.txt
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/CMakeLists.txt?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/test/CMakeLists.txt (original)
> > +++ llvm/trunk/lib/Fuzzer/test/CMakeLists.txt Fri May 22 17:35:31 2015
> > @@ -21,6 +21,10 @@ set(Tests
> > ${DFSanTests}
> > )
> >
> > +set(CustomMainTests
> > + UserSuppliedFuzzerTest
> > + )
> > +
> >
> > set(TestBinaries)
> >
> > @@ -34,6 +38,17 @@ foreach(Test ${Tests})
> > set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test})
> > endforeach()
> >
> > +foreach(Test ${CustomMainTests})
> > + add_executable(LLVMFuzzer-${Test}
> > + ${Test}.cpp
> > + )
> > + target_link_libraries(LLVMFuzzer-${Test}
> > + LLVMFuzzerNoMain
> > + )
> > + set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test})
> > +endforeach()
> > +
> > +
> > configure_lit_site_cfg(
> > ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
> > ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
> > @@ -49,7 +64,7 @@ include_directories(${LLVM_MAIN_SRC_DIR}
> >
> > add_executable(LLVMFuzzer-Unittest
> > FuzzerUnittest.cpp
> > - $<TARGET_OBJECTS:LLVMFuzzerNoMain>
> > + $<TARGET_OBJECTS:LLVMFuzzerNoMainObjects>
> > )
> >
> > target_link_libraries(LLVMFuzzer-Unittest
> >
> > Modified: llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp (original)
> > +++ llvm/trunk/lib/Fuzzer/test/FuzzerUnittest.cpp Fri May 22 17:35:31
> 2015
> > @@ -51,7 +51,10 @@ TEST(Fuzzer, CrossOver) {
> > for (size_t Len = 1; Len < 8; Len++) {
> > std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
> > for (int Iter = 0; Iter < 3000; Iter++) {
> > - CrossOver(A, B, &C, Len);
> > + C.resize(Len);
> > + size_t NewSize = CrossOver(A.data(), A.size(), B.data(), B.size(),
> > + C.data(), C.size());
> > + C.resize(NewSize);
> > FoundUnits.insert(C);
> > }
> > for (const Unit &U : Expected)
> >
> > Added: llvm/trunk/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp?rev=238059&view=auto
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp (added)
> > +++ llvm/trunk/lib/Fuzzer/test/UserSuppliedFuzzerTest.cpp Fri May 22
> 17:35:31 2015
> > @@ -0,0 +1,47 @@
> > +// Simple test for a fuzzer.
> > +// The fuzzer must find the string "Hi!" preceded by a magic value.
> > +// Uses UserSuppliedFuzzer which ensures that the magic is present.
> > +#include <cstdint>
> > +#include <cassert>
> > +#include <cstdlib>
> > +#include <cstddef>
> > +#include <cstring>
> > +#include <iostream>
> > +
> > +#include "FuzzerInterface.h"
> > +
> > +static const uint64_t kMagic = 8860221463604ULL;
> > +
> > +class MyFuzzer : public fuzzer::UserSuppliedFuzzer {
> > + public:
> > + void TargetFunction(const uint8_t *Data, size_t Size) {
> > + if (Size <= 10) return;
> > + if (memcmp(Data, &kMagic, sizeof(kMagic))) return;
> > + // It's hard to get here w/o advanced fuzzing techniques (e.g. cmp
> tracing).
> > + // So, we simply 'fix' the data in the custom mutator.
> > + if (Data[8] == 'H') {
> > + if (Data[9] == 'i') {
> > + if (Data[10] == '!') {
> > + std::cout << "BINGO; Found the target, exiting\n";
> > + exit(1);
> > + }
> > + }
> > + }
> > + }
> > + // Custom mutator.
> > + virtual size_t Mutate(uint8_t *Data, size_t Size, size_t MaxSize) {
> > + assert(MaxSize > sizeof(kMagic));
> > + if (Size < sizeof(kMagic))
> > + Size = sizeof(kMagic);
> > + // "Fix" the data, then mutate.
> > + memcpy(Data, &kMagic, std::min(MaxSize, sizeof(kMagic)));
> > + return BasicMutate(Data + sizeof(kMagic), Size - sizeof(kMagic),
> > + MaxSize - sizeof(kMagic));
> > + }
> > + // No need to redefine CrossOver() here.
> > +};
> > +
> > +int main(int argc, char **argv) {
> > + MyFuzzer F;
> > + fuzzer::FuzzerDriver(argc, argv, F);
> > +}
> >
> > Modified: llvm/trunk/lib/Fuzzer/test/fuzzer.test
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Fuzzer/test/fuzzer.test?rev=238059&r1=238058&r2=238059&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Fuzzer/test/fuzzer.test (original)
> > +++ llvm/trunk/lib/Fuzzer/test/fuzzer.test Fri May 22 17:35:31 2015
> > @@ -26,3 +26,5 @@ RUN: not ./LLVMFuzzer-DFSanMemcmpTest-DF
> >
> > RUN: not ./LLVMFuzzer-CxxTokensTest -seed=1 -timeout=15
> -tokens=%S/../cxx_fuzzer_tokens.txt 2>&1 | FileCheck %s
> >
> > +RUN: not ./LLVMFuzzer-UserSuppliedFuzzerTest -seed=1 -timeout=15 2>&1 |
> FileCheck %s
> > +
> >
> >
> > _______________________________________________
> > llvm-commits mailing list
> > llvm-commits at cs.uiuc.edu
> > http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150522/c0dcb463/attachment.html>
More information about the llvm-commits
mailing list