From f316f2ea52196f572a05d607e6953274c399c8ce Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 29 Jan 2015 15:49:22 +0000 Subject: [PATCH] Temporarily reverting the fuzzer library as it causes too many build issues for MSVC users. This reverts: 227445, 227395, 227389, 227357, 227254, 227252 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227452 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CMakeLists.txt | 1 - lib/Fuzzer/CMakeLists.txt | 13 -- lib/Fuzzer/FuzzerCrossOver.cpp | 47 ------- lib/Fuzzer/FuzzerFlags.def | 27 ---- lib/Fuzzer/FuzzerIO.cpp | 49 ------- lib/Fuzzer/FuzzerInternal.h | 81 ----------- lib/Fuzzer/FuzzerLoop.cpp | 170 ------------------------ lib/Fuzzer/FuzzerMain.cpp | 148 --------------------- lib/Fuzzer/FuzzerMutate.cpp | 62 --------- lib/Fuzzer/FuzzerUtil.cpp | 61 --------- lib/Fuzzer/README.txt | 64 --------- lib/Fuzzer/test/CMakeLists.txt | 37 ------ lib/Fuzzer/test/ExactTest.cpp | 22 --- lib/Fuzzer/test/InfiniteTest.cpp | 20 --- lib/Fuzzer/test/NullDerefTest.cpp | 22 --- lib/Fuzzer/test/SimpleTest.cpp | 21 --- lib/Fuzzer/test/TestFuzzerCrossOver.cpp | 13 -- lib/Fuzzer/test/TimeoutTest.cpp | 22 --- lib/Fuzzer/test/fuzzer.test | 13 -- lib/Fuzzer/test/lit.cfg | 6 - lib/Fuzzer/test/lit.site.cfg.in | 2 - 21 files changed, 901 deletions(-) delete mode 100644 lib/Fuzzer/CMakeLists.txt delete mode 100644 lib/Fuzzer/FuzzerCrossOver.cpp delete mode 100644 lib/Fuzzer/FuzzerFlags.def delete mode 100644 lib/Fuzzer/FuzzerIO.cpp delete mode 100644 lib/Fuzzer/FuzzerInternal.h delete mode 100644 lib/Fuzzer/FuzzerLoop.cpp delete mode 100644 lib/Fuzzer/FuzzerMain.cpp delete mode 100644 lib/Fuzzer/FuzzerMutate.cpp delete mode 100644 lib/Fuzzer/FuzzerUtil.cpp delete mode 100644 lib/Fuzzer/README.txt delete mode 100644 lib/Fuzzer/test/CMakeLists.txt delete mode 100644 lib/Fuzzer/test/ExactTest.cpp delete mode 100644 lib/Fuzzer/test/InfiniteTest.cpp delete mode 100644 lib/Fuzzer/test/NullDerefTest.cpp delete mode 100644 lib/Fuzzer/test/SimpleTest.cpp delete mode 100644 lib/Fuzzer/test/TestFuzzerCrossOver.cpp delete mode 100644 lib/Fuzzer/test/TimeoutTest.cpp delete mode 100644 lib/Fuzzer/test/fuzzer.test delete mode 100644 lib/Fuzzer/test/lit.cfg delete mode 100644 lib/Fuzzer/test/lit.site.cfg.in diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 8ab2d6e9de7..fab1c8747b9 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -17,4 +17,3 @@ add_subdirectory(Target) add_subdirectory(AsmParser) add_subdirectory(LineEditor) add_subdirectory(ProfileData) -add_subdirectory(Fuzzer) diff --git a/lib/Fuzzer/CMakeLists.txt b/lib/Fuzzer/CMakeLists.txt deleted file mode 100644 index e1ff65848cc..00000000000 --- a/lib/Fuzzer/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_library(LLVMFuzzer STATIC - EXCLUDE_FROM_ALL # Do not build if you are not building fuzzers. - FuzzerCrossOver.cpp - FuzzerIO.cpp - FuzzerLoop.cpp - FuzzerMain.cpp - FuzzerMutate.cpp - FuzzerUtil.cpp - ) - -if( LLVM_INCLUDE_TESTS ) - add_subdirectory(test) -endif() diff --git a/lib/Fuzzer/FuzzerCrossOver.cpp b/lib/Fuzzer/FuzzerCrossOver.cpp deleted file mode 100644 index 94af6d547ed..00000000000 --- a/lib/Fuzzer/FuzzerCrossOver.cpp +++ /dev/null @@ -1,47 +0,0 @@ -//===- FuzzerCrossOver.cpp - Cross over two test inputs -------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Cross over test inputs. -//===----------------------------------------------------------------------===// - -#include "FuzzerInternal.h" -#include - -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); - 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; - } - } -} - -} // namespace fuzzer diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def deleted file mode 100644 index e165ebdbf37..00000000000 --- a/lib/Fuzzer/FuzzerFlags.def +++ /dev/null @@ -1,27 +0,0 @@ -//===- FuzzerFlags.def - Run-time flags -------------------------*- C++ -* ===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Flags. FUZZER_FLAG macro should be defined at the point of inclusion. -// We are not using any flag parsing library for better portability and -// independence. -//===----------------------------------------------------------------------===// -FUZZER_FLAG(int, verbosity, 1, "Verbosity level.") -FUZZER_FLAG(int, seed, 0, "Random seed. If 0, seed is generated.") -FUZZER_FLAG(int, iterations, -1, - "Number of iterations of the fuzzer (-1 for infinite runs).") -FUZZER_FLAG(int, max_len, 64, "Maximal length of the test input.") -FUZZER_FLAG(int, cross_over, 1, "If 1, cross over inputs.") -FUZZER_FLAG(int, mutate_depth, 10, - "Apply this number of consecutive mutations to each input.") -FUZZER_FLAG(int, exit_on_first, 0, - "If 1, exit after the first new interesting input is found.") -FUZZER_FLAG(int, timeout, -1, "Timeout in seconds (if positive).") -FUZZER_FLAG(int, help, 0, "Print help.") -FUZZER_FLAG( - int, save_minimized_corpus, 0, - "If 1, the minimized corpus is saved into the first input directory") diff --git a/lib/Fuzzer/FuzzerIO.cpp b/lib/Fuzzer/FuzzerIO.cpp deleted file mode 100644 index 4e0ac819218..00000000000 --- a/lib/Fuzzer/FuzzerIO.cpp +++ /dev/null @@ -1,49 +0,0 @@ -//===- FuzzerIO.cpp - IO utils. -------------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// IO functions. -//===----------------------------------------------------------------------===// -#include "FuzzerInternal.h" -#include -#include -namespace fuzzer { - -static std::vector ListFilesInDir(const std::string &Dir) { - std::vector V; - DIR *D = opendir(Dir.c_str()); - if (!D) return V; - while (auto E = readdir(D)) { - if (E->d_type == DT_REG || E->d_type == DT_LNK) - V.push_back(E->d_name); - } - closedir(D); - return V; -} - -Unit FileToVector(const std::string &Path) { - std::ifstream T(Path); - return Unit((std::istreambuf_iterator(T)), - std::istreambuf_iterator()); -} - -void WriteToFile(const Unit &U, const std::string &Path) { - std::ofstream OF(Path); - OF.write((const char*)U.data(), U.size()); -} - -void ReadDirToVectorOfUnits(const char *Path, std::vector *V) { - for (auto &X : ListFilesInDir(Path)) - V->push_back(FileToVector(DirPlusFile(Path, X))); -} - -std::string DirPlusFile(const std::string &DirPath, - const std::string &FileName) { - return DirPath + "/" + FileName; -} - -} // namespace fuzzer diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h deleted file mode 100644 index c361ffba83a..00000000000 --- a/lib/Fuzzer/FuzzerInternal.h +++ /dev/null @@ -1,81 +0,0 @@ -//===- FuzzerInternal.h - Internal header for the Fuzzer --------*- C++ -* ===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Define the main class fuzzer::Fuzzer and most functions. -//===----------------------------------------------------------------------===// -#include -#include -#include -#include -#include -#include - -namespace fuzzer { -typedef std::vector Unit; -using namespace std::chrono; - -Unit ReadFile(const char *Path); -void ReadDirToVectorOfUnits(const char *Path, std::vector *V); -void WriteToFile(const Unit &U, const std::string &Path); -// Returns "Dir/FileName" or equivalent for the current OS. -std::string DirPlusFile(const std::string &DirPath, - const std::string &FileName); - -void Mutate(Unit *U, size_t MaxLen); - -void CrossOver(const Unit &A, const Unit &B, Unit *U, size_t MaxLen); - -void Print(const Unit &U, const char *PrintAfter = ""); -void PrintASCII(const Unit &U, const char *PrintAfter = ""); -std::string Hash(const Unit &U); -void SetTimer(int Seconds); - -class Fuzzer { - public: - struct FuzzingOptions { - int Verbosity = 1; - int MaxLen = 0; - bool DoCrossOver = true; - bool MutateDepth = 10; - bool ExitOnFirst = false; - std::string OutputCorpus; - }; - Fuzzer(FuzzingOptions Options) : Options(Options) { - SetDeathCallback(); - } - void AddToCorpus(const Unit &U) { Corpus.push_back(U); } - size_t Loop(size_t NumIterations); - void ShuffleAndMinimize(); - size_t CorpusSize() const { return Corpus.size(); } - void ReadDir(const std::string &Path) { - ReadDirToVectorOfUnits(Path.c_str(), &Corpus); - } - // Save the current corpus to OutputCorpus. - void SaveCorpus(); - - static void AlarmCallback(); - - private: - size_t MutateAndTestOne(Unit *U); - size_t RunOne(const Unit &U); - void WriteToOutputCorpus(const Unit &U); - static void WriteToCrash(const Unit &U, const char *Prefix); - - void SetDeathCallback(); - static void DeathCallback(); - static Unit CurrentUnit; - - size_t TotalNumberOfRuns = 0; - - std::vector Corpus; - FuzzingOptions Options; - system_clock::time_point ProcessStartTime = system_clock::now(); - static system_clock::time_point UnitStartTime; -}; - -}; // namespace fuzzer diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp deleted file mode 100644 index 1f2193a45b3..00000000000 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//===- FuzzerLoop.cpp - Fuzzer's main loop --------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Fuzzer's main loop. -//===----------------------------------------------------------------------===// - -#include "FuzzerInternal.h" -#include -#include -#include -#include -#include - -// This function should be defined by the user. -extern "C" void TestOneInput(const uint8_t *Data, size_t Size); - -namespace fuzzer { - -// static -Unit Fuzzer::CurrentUnit; -system_clock::time_point Fuzzer::UnitStartTime; - -void Fuzzer::SetDeathCallback() { - __sanitizer_set_death_callback(DeathCallback); -} - -void Fuzzer::DeathCallback() { - std::cerr << "DEATH: " << std::endl; - Print(CurrentUnit, "\n"); - PrintASCII(CurrentUnit, "\n"); - WriteToCrash(CurrentUnit, "crash-"); -} - -void Fuzzer::AlarmCallback() { - size_t Seconds = - duration_cast(system_clock::now() - UnitStartTime).count(); - std::cerr << "ALARM: working on the last Unit for " << Seconds << " seconds" - << std::endl; - if (Seconds >= 3) { - Print(CurrentUnit, "\n"); - PrintASCII(CurrentUnit, "\n"); - WriteToCrash(CurrentUnit, "timeout-"); - } - exit(1); -} - -void Fuzzer::ShuffleAndMinimize() { - if (Options.Verbosity) - std::cerr << "Shuffle: " << Corpus.size() << "\n"; - std::vector NewCorpus; - random_shuffle(Corpus.begin(), Corpus.end()); - size_t MaxCov = 0; - Unit &U = CurrentUnit; - for (const auto &C : Corpus) { - for (size_t First = 0; First < 1; First++) { - U.clear(); - size_t Last = std::min(First + Options.MaxLen, C.size()); - U.insert(U.begin(), C.begin() + First, C.begin() + Last); - size_t NewCoverage = RunOne(U); - if (NewCoverage) { - MaxCov = NewCoverage; - NewCorpus.push_back(U); - if (Options.Verbosity >= 2) - std::cerr << "NEW0: " << NewCoverage << "\n"; - } - } - } - Corpus = NewCorpus; - if (Options.Verbosity) - std::cerr << "Shuffle done: " << Corpus.size() << " IC: " << MaxCov << "\n"; -} - -size_t Fuzzer::RunOne(const Unit &U) { - UnitStartTime = system_clock::now(); - TotalNumberOfRuns++; - size_t OldCoverage = __sanitizer_get_total_unique_coverage(); - TestOneInput(U.data(), U.size()); - size_t NewCoverage = __sanitizer_get_total_unique_coverage(); - if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) && Options.Verbosity) { - size_t Seconds = - duration_cast(system_clock::now() - ProcessStartTime).count(); - std::cerr - << "#" << TotalNumberOfRuns - << "\tcov: " << NewCoverage - << "\texec/s: " << (Seconds ? TotalNumberOfRuns / Seconds : 0) << "\n"; - } - if (NewCoverage > OldCoverage) - return NewCoverage; - return 0; -} - -void Fuzzer::WriteToOutputCorpus(const Unit &U) { - if (Options.OutputCorpus.empty()) return; - std::string Path = DirPlusFile(Options.OutputCorpus, Hash(U)); - WriteToFile(U, Path); - if (Options.Verbosity >= 2) - std::cerr << "Written to " << Path << std::endl; -} - -void Fuzzer::WriteToCrash(const Unit &U, const char *Prefix) { - std::string Path = Prefix + Hash(U); - WriteToFile(U, Path); - std::cerr << "CRASHED; file written to " << Path << std::endl; -} - -void Fuzzer::SaveCorpus() { - if (Options.OutputCorpus.empty()) return; - for (const auto &U : Corpus) - WriteToFile(U, DirPlusFile(Options.OutputCorpus, Hash(U))); - if (Options.Verbosity) - std::cerr << "Written corpus of " << Corpus.size() << " files to " - << Options.OutputCorpus << "\n"; -} - -size_t Fuzzer::MutateAndTestOne(Unit *U) { - size_t NewUnits = 0; - for (size_t i = 0; i < Options.MutateDepth; i++) { - Mutate(U, Options.MaxLen); - if (U->empty()) continue; - size_t NewCoverage = RunOne(*U); - if (NewCoverage) { - Corpus.push_back(*U); - NewUnits++; - if (Options.Verbosity) { - std::cerr << "#" << TotalNumberOfRuns - << "\tNEW: " << NewCoverage - << " L: " << U->size() - << "\t"; - if (U->size() < 30) { - PrintASCII(*U); - std::cerr << "\t"; - Print(*U); - } - std::cerr << "\n"; - } - WriteToOutputCorpus(*U); - if (Options.ExitOnFirst) - exit(0); - } - } - return NewUnits; -} - -size_t Fuzzer::Loop(size_t NumIterations) { - size_t NewUnits = 0; - for (size_t i = 1; i <= NumIterations; i++) { - if (Options.DoCrossOver) { - for (size_t J1 = 0; J1 < Corpus.size(); J1++) { - for (size_t J2 = 0; J2 < Corpus.size(); J2++) { - CurrentUnit.clear(); - CrossOver(Corpus[J1], Corpus[J2], &CurrentUnit, Options.MaxLen); - NewUnits += MutateAndTestOne(&CurrentUnit); - } - } - } else { // No CrossOver - for (size_t J = 0; J < Corpus.size(); J++) { - CurrentUnit = Corpus[J]; - NewUnits += MutateAndTestOne(&CurrentUnit); - } - } - } - return NewUnits; -} - -} // namespace fuzzer diff --git a/lib/Fuzzer/FuzzerMain.cpp b/lib/Fuzzer/FuzzerMain.cpp deleted file mode 100644 index 6031fc835b9..00000000000 --- a/lib/Fuzzer/FuzzerMain.cpp +++ /dev/null @@ -1,148 +0,0 @@ -//===- FuzzerMain.cpp - main() function and flags -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// main() and flags. -//===----------------------------------------------------------------------===// - -#include "FuzzerInternal.h" - -#include -#include -#include -#include - -// ASAN options: -// * don't dump the coverage to disk. -// * enable coverage by default. -extern "C" const char *__asan_default_options() { - return "coverage_pcs=0:coverage=1"; -} - -// Program arguments. -struct FlagDescription { - const char *Name; - const char *Description; - int Default; - int *Flag; -}; - -struct { -#define FUZZER_FLAG(Type, Name, Default, Description) Type Name; -#include "FuzzerFlags.def" -#undef FUZZER_FLAG -} Flags; - -static FlagDescription FlagDescriptions [] { -#define FUZZER_FLAG(Type, Name, Default, Description) {#Name, Description, Default, &Flags.Name}, -#include "FuzzerFlags.def" -#undef FUZZER_FLAG -}; - -static const size_t kNumFlags = - sizeof(FlagDescriptions) / sizeof(FlagDescriptions[0]); - -static std::vector inputs; -static const char *ProgName; - -static void PrintHelp() { - std::cerr << "Usage: " << ProgName - << " [-flag1=val1 [-flag2=val2 ...] ] [dir1 [dir2 ...] ]\n"; - std::cerr << "\nFlags: (strictly in form -flag=value)\n"; - size_t MaxFlagLen = 0; - for (size_t F = 0; F < kNumFlags; F++) - MaxFlagLen = std::max(strlen(FlagDescriptions[F].Name), MaxFlagLen); - - for (size_t F = 0; F < kNumFlags; F++) { - const auto &D = FlagDescriptions[F]; - std::cerr << " " << D.Name; - for (size_t i = 0, n = MaxFlagLen - strlen(D.Name); i < n; i++) - std::cerr << " "; - std::cerr << "\t"; - std::cerr << D.Default << "\t" << D.Description << "\n"; - } -} - -static const char *FlagValue(const char *Param, const char *Name) { - size_t Len = strlen(Name); - if (Param[0] == '-' && strstr(Param + 1, Name) == Param + 1 && - Param[Len + 1] == '=') - return &Param[Len + 2]; - return nullptr; -} - -static bool ParseOneFlag(const char *Param) { - if (Param[0] != '-') return false; - for (size_t F = 0; F < kNumFlags; F++) { - const char *Name = FlagDescriptions[F].Name; - const char *Str = FlagValue(Param, Name); - if (Str) { - int Val = std::stol(Str); - *FlagDescriptions[F].Flag = Val; - if (Flags.verbosity >= 2) - std::cerr << "Flag: " << Name << " " << Val << "\n"; - return true; - } - } - PrintHelp(); - exit(1); -} - -// We don't use any library to minimize dependencies. -static void ParseFlags(int argc, char **argv) { - for (size_t F = 0; F < kNumFlags; F++) - *FlagDescriptions[F].Flag = FlagDescriptions[F].Default; - for (int A = 1; A < argc; A++) { - if (ParseOneFlag(argv[A])) continue; - inputs.push_back(argv[A]); - } -} - -int main(int argc, char **argv) { - using namespace fuzzer; - - ProgName = argv[0]; - ParseFlags(argc, argv); - if (Flags.help) { - PrintHelp(); - return 0; - } - Fuzzer::FuzzingOptions Options; - Options.Verbosity = Flags.verbosity; - Options.MaxLen = Flags.max_len; - Options.DoCrossOver = Flags.cross_over; - Options.MutateDepth = Flags.mutate_depth; - Options.ExitOnFirst = Flags.exit_on_first; - if (!inputs.empty()) - Options.OutputCorpus = inputs[0]; - Fuzzer F(Options); - - unsigned seed = Flags.seed; - // Initialize seed. - if (seed == 0) - seed = time(0) * 10000 + getpid(); - if (Flags.verbosity) - std::cerr << "Seed: " << seed << "\n"; - srand(seed); - - // Timer - if (Flags.timeout > 0) - SetTimer(Flags.timeout); - - for (auto &inp : inputs) - F.ReadDir(inp); - - if (F.CorpusSize() == 0) - F.AddToCorpus(Unit()); // Can't fuzz empty corpus, so add an empty input. - F.ShuffleAndMinimize(); - if (Flags.save_minimized_corpus) - F.SaveCorpus(); - F.Loop(Flags.iterations < 0 ? INT_MAX : Flags.iterations); - if (Flags.verbosity) - std::cerr << "Done\n"; - return 1; -} diff --git a/lib/Fuzzer/FuzzerMutate.cpp b/lib/Fuzzer/FuzzerMutate.cpp deleted file mode 100644 index 2db8fac9bc6..00000000000 --- a/lib/Fuzzer/FuzzerMutate.cpp +++ /dev/null @@ -1,62 +0,0 @@ -//===- FuzzerMutate.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. -// -//===----------------------------------------------------------------------===// -// Mutate a test input. -//===----------------------------------------------------------------------===// - -#include "FuzzerInternal.h" - -namespace fuzzer { - -static char FlipRandomBit(char X) { - int Bit = rand() % 8; - char Mask = 1 << Bit; - char R; - if (X & (1 << Bit)) - R = X & ~Mask; - else - R = X | Mask; - assert(R != X); - return R; -} - -static char RandCh() { - if (rand() % 2) return rand(); - const char *Special = "!*'();:@&=+$,/?%#[]123ABCxyz-`~."; - return Special[rand() % (sizeof(Special) - 1)]; -} - -void Mutate(Unit *U, size_t MaxLen) { - assert(MaxLen > 0); - assert(U->size() <= MaxLen); - switch (rand() % 3) { - case 0: - if (U->size()) - U->erase(U->begin() + rand() % U->size()); - break; - case 1: - if (U->empty()) { - U->push_back(RandCh()); - } else 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; - } - break; - default: - if (!U->empty()) { - size_t idx = rand() % U->size(); - (*U)[idx] = FlipRandomBit((*U)[idx]); - } - break; - } -} - -} // namespace fuzzer diff --git a/lib/Fuzzer/FuzzerUtil.cpp b/lib/Fuzzer/FuzzerUtil.cpp deleted file mode 100644 index 679f289a1c3..00000000000 --- a/lib/Fuzzer/FuzzerUtil.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//===- FuzzerUtil.cpp - Misc utils ----------------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Misc utils. -//===----------------------------------------------------------------------===// - -#include "FuzzerInternal.h" -#include -#include -#include -#include -#include - -namespace fuzzer { - -void Print(const Unit &v, const char *PrintAfter) { - std::cerr << v.size() << ": "; - for (auto x : v) - std::cerr << (unsigned) x << " "; - std::cerr << PrintAfter; -} - -void PrintASCII(const Unit &U, const char *PrintAfter) { - for (auto X : U) - std::cerr << (char)((isascii(X) && X >= ' ') ? X : '?'); - std::cerr << PrintAfter; -} - -std::string Hash(const Unit &in) { - size_t h1 = 0, h2 = 0; - for (auto x : in) { - h1 += x; - h1 *= 5; - h2 += x; - h2 *= 7; - } - return std::to_string(h1) + std::to_string(h2); -} - -static void AlarmHandler(int, siginfo_t *, void *) { - Fuzzer::AlarmCallback(); -} - -void SetTimer(int Seconds) { - struct itimerval T {{Seconds, 0}, {Seconds, 0}}; - std::cerr << "SetTimer " << Seconds << "\n"; - int Res = setitimer(ITIMER_REAL, &T, nullptr); - assert(Res == 0); - struct sigaction sigact; - memset(&sigact, 0, sizeof(sigact)); - sigact.sa_sigaction = AlarmHandler; - Res = sigaction(SIGALRM, &sigact, 0); - assert(Res == 0); -} - -} // namespace fuzzer diff --git a/lib/Fuzzer/README.txt b/lib/Fuzzer/README.txt deleted file mode 100644 index 5f2c3a83515..00000000000 --- a/lib/Fuzzer/README.txt +++ /dev/null @@ -1,64 +0,0 @@ -=============================== -Fuzzer -- a library for coverage-guided fuzz testing. -=============================== - -This library is intended primarily for in-process coverage-guided fuzz testing -(fuzzing) of other libraries. The typical workflow looks like this: - - * Build the Fuzzer library as a static archive (or just a set of .o files). - Note that the Fuzzer contains the main() function. - Preferably do *not* use sanitizers while building the Fuzzer. - * Build the library you are going to test with -fsanitize-coverage=[234] - and one of the sanitizers. We recommend to build the library in several - different modes (e.g. asan, msan, lsan, ubsan, etc) and even using different - optimizations options (e.g. -O0, -O1, -O2) to diversify testing. - * Build a test driver using the same options as the library. - The test driver is a C/C++ file containing interesting calls to the library - inside a single function: - extern "C" void TestOneInput(const uint8_t *Data, size_t Size); - * Link the Fuzzer, the library and the driver together into an executable - using the same sanitizer options as for the library. - * Collect the initial corpus of inputs for the - fuzzer (a directory with test inputs, one file per input). - The better your inputs are the faster you will find something interesting. - Also try to keep your inputs small, otherwise the Fuzzer will run too slow. - * Run the fuzzer with the test corpus. As new interesting test cases are - discovered they will be added to the corpus. If a bug is discovered by - the sanitizer (asan, etc) it will be reported as usual and the reproducer - will be written to disk. - Each Fuzzer process is single-threaded (unless the library starts its own - threads). You can run the Fuzzer on the same corpus in multiple processes. - in parallel. For run-time options run the Fuzzer binary with '-help=1'. - - -The Fuzzer is similar in concept to AFL (http://lcamtuf.coredump.cx/afl/), -but uses in-process Fuzzing, which is more fragile, more restrictive, but -potentially much faster as it has no overhead for process start-up. -It uses LLVM's "Sanitizer Coverage" instrumentation to get in-process -coverage-feedback https://code.google.com/p/address-sanitizer/wiki/AsanCoverage - -The code resides in the LLVM repository and is (or will be) used by various -parts of LLVM, but the Fuzzer itself does not (and should not) depend on any -part of LLVM and can be used for other projects. Ideally, the Fuzzer's code -should not have any external dependencies. Right now it uses STL, which may need -to be fixed later. - -Examples of usage in LLVM: - * clang-format-fuzzer. The inputs are random pieces of C++-like text. - * Build (make sure to use fresh clang as the host compiler): - cmake -GNinja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ \ - -DLLVM_USE_SANITIZER=Address -DLLVM_USE_SANITIZE_COVERAGE=YES \ - /path/to/llvm -DCMAKE_BUILD_TYPE=Release - ninja clang-format-fuzzer - * Optionally build other kinds of binaries (asan+Debug, msan, ubsan, etc) - * TODO: commit the pre-fuzzed corpus to svn (?). - * Run: - clang-format-fuzzer CORPUS_DIR - -Toy example (see SimpleTest.cpp): -a simple function that does something interesting if it receives bytes "Hi!". - # Build the Fuzzer with asan: - % clang++ -std=c++11 -fsanitize=address -fsanitize-coverage=3 -O1 -g \ - Fuzzer*.cpp test/SimpleTest.cpp - # Run the fuzzer with no corpus (assuming on empty input) - % ./a.out diff --git a/lib/Fuzzer/test/CMakeLists.txt b/lib/Fuzzer/test/CMakeLists.txt deleted file mode 100644 index 0c2118f31b0..00000000000 --- a/lib/Fuzzer/test/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -set(Tests - ExactTest - InfiniteTest - NullDerefTest - SimpleTest - TimeoutTest - ) - -set(TestBinaries) - -foreach(Test ${Tests}) - add_executable(LLVMFuzzer-${Test} - EXCLUDE_FROM_ALL - ${Test}.cpp - ) - target_link_libraries(LLVMFuzzer-${Test} - LLVMFuzzer - ) - set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}) -endforeach() - -set_target_properties(${TestBinaries} - PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - -set(EXCLUDE_FROM_ALL TRUE) -add_lit_testsuite(check-fuzzer "Running Fuzzer tests" - ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS ${TestBinaries} - ) -set(EXCLUDE_FROM_ALL FALSE) - -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg - ) - diff --git a/lib/Fuzzer/test/ExactTest.cpp b/lib/Fuzzer/test/ExactTest.cpp deleted file mode 100644 index c9898f3c811..00000000000 --- a/lib/Fuzzer/test/ExactTest.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Simple test for a fuzzer. The fuzzer must find the string "FUZZER". -#include -#include -#include -#include - -static volatile int Sink; - -extern "C" void TestOneInput(const uint8_t *Data, size_t Size) { - int bits = 0; - if (Size > 0 && Data[0] == 'F') bits |= 1; - if (Size > 1 && Data[1] == 'U') bits |= 2; - if (Size > 2 && Data[2] == 'Z') bits |= 4; - if (Size > 3 && Data[3] == 'Z') bits |= 8; - if (Size > 4 && Data[4] == 'E') bits |= 16; - if (Size > 5 && Data[5] == 'R') bits |= 32; - if (bits == 63) { - std::cerr << "BINGO!\n"; - abort(); - } -} - diff --git a/lib/Fuzzer/test/InfiniteTest.cpp b/lib/Fuzzer/test/InfiniteTest.cpp deleted file mode 100644 index ee1635d1996..00000000000 --- a/lib/Fuzzer/test/InfiniteTest.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// Simple test for a fuzzer. The fuzzer must find the string "Hi!". -#include -#include -#include -#include - -static volatile int Sink; - -extern "C" void TestOneInput(const uint8_t *Data, size_t Size) { - if (Size > 0 && Data[0] == 'H') { - Sink = 1; - if (Size > 1 && Data[1] == 'i') { - Sink = 2; - if (Size > 2 && Data[2] == '!') { - Size = 2; - } - } - } -} - diff --git a/lib/Fuzzer/test/NullDerefTest.cpp b/lib/Fuzzer/test/NullDerefTest.cpp deleted file mode 100644 index 8811e386f9d..00000000000 --- a/lib/Fuzzer/test/NullDerefTest.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Simple test for a fuzzer. The fuzzer must find the string "Hi!". -#include -#include -#include -#include - -static volatile int Sink; -static volatile int *Null = 0; - -extern "C" void TestOneInput(const uint8_t *Data, size_t Size) { - if (Size > 0 && Data[0] == 'H') { - Sink = 1; - if (Size > 1 && Data[1] == 'i') { - Sink = 2; - if (Size > 2 && Data[2] == '!') { - std::cout << "Found the target, dereferencing NULL\n"; - *Null = 1; - } - } - } -} - diff --git a/lib/Fuzzer/test/SimpleTest.cpp b/lib/Fuzzer/test/SimpleTest.cpp deleted file mode 100644 index adb90cebe86..00000000000 --- a/lib/Fuzzer/test/SimpleTest.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// Simple test for a fuzzer. The fuzzer must find the string "Hi!". -#include -#include -#include -#include - -static volatile int Sink; - -extern "C" void TestOneInput(const uint8_t *Data, size_t Size) { - if (Size > 0 && Data[0] == 'H') { - Sink = 1; - if (Size > 1 && Data[1] == 'i') { - Sink = 2; - if (Size > 2 && Data[2] == '!') { - std::cout << "Found the target, exiting\n"; - exit(0); - } - } - } -} - diff --git a/lib/Fuzzer/test/TestFuzzerCrossOver.cpp b/lib/Fuzzer/test/TestFuzzerCrossOver.cpp deleted file mode 100644 index 7f7619618ec..00000000000 --- a/lib/Fuzzer/test/TestFuzzerCrossOver.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "FuzzerInternal.h" - -int main() { - using namespace fuzzer; - Unit A({0, 1, 2, 3, 4}), B({5, 6, 7, 8, 9}); - Unit C; - for (size_t Len = 1; Len < 15; Len++) { - for (int Iter = 0; Iter < 1000; Iter++) { - CrossOver(A, B, &C, Len); - Print(C); - } - } -} diff --git a/lib/Fuzzer/test/TimeoutTest.cpp b/lib/Fuzzer/test/TimeoutTest.cpp deleted file mode 100644 index 266ead646a5..00000000000 --- a/lib/Fuzzer/test/TimeoutTest.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// Simple test for a fuzzer. The fuzzer must find the string "Hi!". -#include -#include -#include -#include - -static volatile int Sink; - -extern "C" void TestOneInput(const uint8_t *Data, size_t Size) { - if (Size > 0 && Data[0] == 'H') { - Sink = 1; - if (Size > 1 && Data[1] == 'i') { - Sink = 2; - if (Size > 2 && Data[2] == '!') { - Size = 2; - while (Sink) - ; - } - } - } -} - diff --git a/lib/Fuzzer/test/fuzzer.test b/lib/Fuzzer/test/fuzzer.test deleted file mode 100644 index 5f013109f62..00000000000 --- a/lib/Fuzzer/test/fuzzer.test +++ /dev/null @@ -1,13 +0,0 @@ -RUN: ./LLVMFuzzer-SimpleTest 2>&1 | FileCheck %s --check-prefix=SimpleTest -SimpleTest: Found the target, exiting - -RUN: not ./LLVMFuzzer-InfiniteTest -timeout=2 2>&1 | FileCheck %s --check-prefix=InfiniteTest -InfiniteTest: ALARM: working on the last Unit for -InfiniteTest-NOT: CRASHED; file written to timeout - -RUN: not ./LLVMFuzzer-TimeoutTest -timeout=5 2>&1 | FileCheck %s --check-prefix=TimeoutTest -TimeoutTest: ALARM: working on the last Unit for -TimeoutTest: CRASHED; file written to timeout - -RUN: not ./LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest -NullDerefTest: CRASHED; file written to crash- diff --git a/lib/Fuzzer/test/lit.cfg b/lib/Fuzzer/test/lit.cfg deleted file mode 100644 index d1c85051b47..00000000000 --- a/lib/Fuzzer/test/lit.cfg +++ /dev/null @@ -1,6 +0,0 @@ -import lit.formats - -config.name = "LLVMFuzzer" -config.test_format = lit.formats.ShTest(True) -config.suffixes = ['.test'] -config.test_source_root = os.path.dirname(__file__) diff --git a/lib/Fuzzer/test/lit.site.cfg.in b/lib/Fuzzer/test/lit.site.cfg.in deleted file mode 100644 index 5fedc1dff6f..00000000000 --- a/lib/Fuzzer/test/lit.site.cfg.in +++ /dev/null @@ -1,2 +0,0 @@ -config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@" -lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")