Home | History | Annotate | Download | only in Fuzzer
      1 //===- FuzzerLoop.cpp - Fuzzer's main loop --------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 // Fuzzer's main loop.
     10 //===----------------------------------------------------------------------===//
     11 
     12 #include "FuzzerInternal.h"
     13 #include <algorithm>
     14 #include <cstring>
     15 #include <memory>
     16 
     17 #if defined(__has_include)
     18 #if __has_include(<sanitizer / coverage_interface.h>)
     19 #include <sanitizer/coverage_interface.h>
     20 #endif
     21 #if __has_include(<sanitizer / lsan_interface.h>)
     22 #include <sanitizer/lsan_interface.h>
     23 #endif
     24 #endif
     25 
     26 #define NO_SANITIZE_MEMORY
     27 #if defined(__has_feature)
     28 #if __has_feature(memory_sanitizer)
     29 #undef NO_SANITIZE_MEMORY
     30 #define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
     31 #endif
     32 #endif
     33 
     34 namespace fuzzer {
     35 static const size_t kMaxUnitSizeToPrint = 256;
     36 
     37 thread_local bool Fuzzer::IsMyThread;
     38 
     39 static void MissingExternalApiFunction(const char *FnName) {
     40   Printf("ERROR: %s is not defined. Exiting.\n"
     41          "Did you use -fsanitize-coverage=... to build your code?\n",
     42          FnName);
     43   exit(1);
     44 }
     45 
     46 #define CHECK_EXTERNAL_FUNCTION(fn)                                            \
     47   do {                                                                         \
     48     if (!(EF->fn))                                                             \
     49       MissingExternalApiFunction(#fn);                                         \
     50   } while (false)
     51 
     52 // Only one Fuzzer per process.
     53 static Fuzzer *F;
     54 
     55 struct CoverageController {
     56   static void Reset() {
     57     CHECK_EXTERNAL_FUNCTION(__sanitizer_reset_coverage);
     58     EF->__sanitizer_reset_coverage();
     59     PcMapResetCurrent();
     60   }
     61 
     62   static void ResetCounters(const FuzzingOptions &Options) {
     63     if (Options.UseCounters) {
     64       EF->__sanitizer_update_counter_bitset_and_clear_counters(0);
     65     }
     66   }
     67 
     68   static void Prepare(const FuzzingOptions &Options, Fuzzer::Coverage *C) {
     69     if (Options.UseCounters) {
     70       size_t NumCounters = EF->__sanitizer_get_number_of_counters();
     71       C->CounterBitmap.resize(NumCounters);
     72     }
     73   }
     74 
     75   // Records data to a maximum coverage tracker. Returns true if additional
     76   // coverage was discovered.
     77   static bool RecordMax(const FuzzingOptions &Options, Fuzzer::Coverage *C) {
     78     bool Res = false;
     79 
     80     uint64_t NewBlockCoverage = EF->__sanitizer_get_total_unique_coverage();
     81     if (NewBlockCoverage > C->BlockCoverage) {
     82       Res = true;
     83       C->BlockCoverage = NewBlockCoverage;
     84     }
     85 
     86     if (Options.UseIndirCalls &&
     87         EF->__sanitizer_get_total_unique_caller_callee_pairs) {
     88       uint64_t NewCallerCalleeCoverage =
     89           EF->__sanitizer_get_total_unique_caller_callee_pairs();
     90       if (NewCallerCalleeCoverage > C->CallerCalleeCoverage) {
     91         Res = true;
     92         C->CallerCalleeCoverage = NewCallerCalleeCoverage;
     93       }
     94     }
     95 
     96     if (Options.UseCounters) {
     97       uint64_t CounterDelta =
     98           EF->__sanitizer_update_counter_bitset_and_clear_counters(
     99               C->CounterBitmap.data());
    100       if (CounterDelta > 0) {
    101         Res = true;
    102         C->CounterBitmapBits += CounterDelta;
    103       }
    104     }
    105 
    106     uint64_t NewPcMapBits = PcMapMergeInto(&C->PCMap);
    107     if (NewPcMapBits > C->PcMapBits) {
    108       Res = true;
    109       C->PcMapBits = NewPcMapBits;
    110     }
    111 
    112     uintptr_t *CoverageBuf;
    113     uint64_t NewPcBufferLen =
    114         EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);
    115     if (NewPcBufferLen > C->PcBufferLen) {
    116       Res = true;
    117       C->PcBufferLen = NewPcBufferLen;
    118     }
    119 
    120     return Res;
    121   }
    122 };
    123 
    124 // Leak detection is expensive, so we first check if there were more mallocs
    125 // than frees (using the sanitizer malloc hooks) and only then try to call lsan.
    126 struct MallocFreeTracer {
    127   void Start() {
    128     Mallocs = 0;
    129     Frees = 0;
    130   }
    131   // Returns true if there were more mallocs than frees.
    132   bool Stop() { return Mallocs > Frees; }
    133   std::atomic<size_t> Mallocs;
    134   std::atomic<size_t> Frees;
    135 };
    136 
    137 static MallocFreeTracer AllocTracer;
    138 
    139 void MallocHook(const volatile void *ptr, size_t size) {
    140   AllocTracer.Mallocs++;
    141 }
    142 void FreeHook(const volatile void *ptr) {
    143   AllocTracer.Frees++;
    144 }
    145 
    146 Fuzzer::Fuzzer(UserCallback CB, MutationDispatcher &MD, FuzzingOptions Options)
    147     : CB(CB), MD(MD), Options(Options) {
    148   SetDeathCallback();
    149   InitializeTraceState();
    150   assert(!F);
    151   F = this;
    152   ResetCoverage();
    153   IsMyThread = true;
    154   if (Options.DetectLeaks && EF->__sanitizer_install_malloc_and_free_hooks)
    155     EF->__sanitizer_install_malloc_and_free_hooks(MallocHook, FreeHook);
    156 }
    157 
    158 void Fuzzer::LazyAllocateCurrentUnitData() {
    159   if (CurrentUnitData || Options.MaxLen == 0) return;
    160   CurrentUnitData = new uint8_t[Options.MaxLen];
    161 }
    162 
    163 void Fuzzer::SetDeathCallback() {
    164   CHECK_EXTERNAL_FUNCTION(__sanitizer_set_death_callback);
    165   EF->__sanitizer_set_death_callback(StaticDeathCallback);
    166 }
    167 
    168 void Fuzzer::StaticDeathCallback() {
    169   assert(F);
    170   F->DeathCallback();
    171 }
    172 
    173 void Fuzzer::DumpCurrentUnit(const char *Prefix) {
    174   if (!CurrentUnitData) return;  // Happens when running individual inputs.
    175   size_t UnitSize = CurrentUnitSize;
    176   if (UnitSize <= kMaxUnitSizeToPrint) {
    177     PrintHexArray(CurrentUnitData, UnitSize, "\n");
    178     PrintASCII(CurrentUnitData, UnitSize, "\n");
    179   }
    180   WriteUnitToFileWithPrefix({CurrentUnitData, CurrentUnitData + UnitSize},
    181                             Prefix);
    182 }
    183 
    184 NO_SANITIZE_MEMORY
    185 void Fuzzer::DeathCallback() {
    186   DumpCurrentUnit("crash-");
    187   PrintFinalStats();
    188 }
    189 
    190 void Fuzzer::StaticAlarmCallback() {
    191   assert(F);
    192   F->AlarmCallback();
    193 }
    194 
    195 void Fuzzer::StaticCrashSignalCallback() {
    196   assert(F);
    197   F->CrashCallback();
    198 }
    199 
    200 void Fuzzer::StaticInterruptCallback() {
    201   assert(F);
    202   F->InterruptCallback();
    203 }
    204 
    205 void Fuzzer::CrashCallback() {
    206   Printf("==%d== ERROR: libFuzzer: deadly signal\n", GetPid());
    207   if (EF->__sanitizer_print_stack_trace)
    208     EF->__sanitizer_print_stack_trace();
    209   Printf("NOTE: libFuzzer has rudimentary signal handlers.\n"
    210          "      Combine libFuzzer with AddressSanitizer or similar for better "
    211          "crash reports.\n");
    212   Printf("SUMMARY: libFuzzer: deadly signal\n");
    213   DumpCurrentUnit("crash-");
    214   PrintFinalStats();
    215   exit(Options.ErrorExitCode);
    216 }
    217 
    218 void Fuzzer::InterruptCallback() {
    219   Printf("==%d== libFuzzer: run interrupted; exiting\n", GetPid());
    220   PrintFinalStats();
    221   _Exit(0);  // Stop right now, don't perform any at-exit actions.
    222 }
    223 
    224 NO_SANITIZE_MEMORY
    225 void Fuzzer::AlarmCallback() {
    226   assert(Options.UnitTimeoutSec > 0);
    227   if (!InFuzzingThread()) return;
    228   if (!CurrentUnitSize)
    229     return; // We have not started running units yet.
    230   size_t Seconds =
    231       duration_cast<seconds>(system_clock::now() - UnitStartTime).count();
    232   if (Seconds == 0)
    233     return;
    234   if (Options.Verbosity >= 2)
    235     Printf("AlarmCallback %zd\n", Seconds);
    236   if (Seconds >= (size_t)Options.UnitTimeoutSec) {
    237     Printf("ALARM: working on the last Unit for %zd seconds\n", Seconds);
    238     Printf("       and the timeout value is %d (use -timeout=N to change)\n",
    239            Options.UnitTimeoutSec);
    240     DumpCurrentUnit("timeout-");
    241     Printf("==%d== ERROR: libFuzzer: timeout after %d seconds\n", GetPid(),
    242            Seconds);
    243     if (EF->__sanitizer_print_stack_trace)
    244       EF->__sanitizer_print_stack_trace();
    245     Printf("SUMMARY: libFuzzer: timeout\n");
    246     PrintFinalStats();
    247     _Exit(Options.TimeoutExitCode); // Stop right now.
    248   }
    249 }
    250 
    251 void Fuzzer::RssLimitCallback() {
    252   Printf(
    253       "==%d== ERROR: libFuzzer: out-of-memory (used: %zdMb; limit: %zdMb)\n",
    254       GetPid(), GetPeakRSSMb(), Options.RssLimitMb);
    255   Printf("   To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");
    256   if (EF->__sanitizer_print_memory_profile)
    257     EF->__sanitizer_print_memory_profile(50);
    258   DumpCurrentUnit("oom-");
    259   Printf("SUMMARY: libFuzzer: out-of-memory\n");
    260   PrintFinalStats();
    261   _Exit(Options.ErrorExitCode); // Stop right now.
    262 }
    263 
    264 void Fuzzer::PrintStats(const char *Where, const char *End) {
    265   size_t ExecPerSec = execPerSec();
    266   if (Options.OutputCSV) {
    267     static bool csvHeaderPrinted = false;
    268     if (!csvHeaderPrinted) {
    269       csvHeaderPrinted = true;
    270       Printf("runs,block_cov,bits,cc_cov,corpus,execs_per_sec,tbms,reason\n");
    271     }
    272     Printf("%zd,%zd,%zd,%zd,%zd,%zd,%s\n", TotalNumberOfRuns,
    273            MaxCoverage.BlockCoverage, MaxCoverage.CounterBitmapBits,
    274            MaxCoverage.CallerCalleeCoverage, Corpus.size(), ExecPerSec, Where);
    275   }
    276 
    277   if (!Options.Verbosity)
    278     return;
    279   Printf("#%zd\t%s", TotalNumberOfRuns, Where);
    280   if (MaxCoverage.BlockCoverage)
    281     Printf(" cov: %zd", MaxCoverage.BlockCoverage);
    282   if (MaxCoverage.PcMapBits)
    283     Printf(" path: %zd", MaxCoverage.PcMapBits);
    284   if (auto TB = MaxCoverage.CounterBitmapBits)
    285     Printf(" bits: %zd", TB);
    286   if (MaxCoverage.CallerCalleeCoverage)
    287     Printf(" indir: %zd", MaxCoverage.CallerCalleeCoverage);
    288   Printf(" units: %zd exec/s: %zd", Corpus.size(), ExecPerSec);
    289   Printf("%s", End);
    290 }
    291 
    292 void Fuzzer::PrintFinalStats() {
    293   if (!Options.PrintFinalStats) return;
    294   size_t ExecPerSec = execPerSec();
    295   Printf("stat::number_of_executed_units: %zd\n", TotalNumberOfRuns);
    296   Printf("stat::average_exec_per_sec:     %zd\n", ExecPerSec);
    297   Printf("stat::new_units_added:          %zd\n", NumberOfNewUnitsAdded);
    298   Printf("stat::slowest_unit_time_sec:    %zd\n", TimeOfLongestUnitInSeconds);
    299   Printf("stat::peak_rss_mb:              %zd\n", GetPeakRSSMb());
    300 }
    301 
    302 size_t Fuzzer::MaxUnitSizeInCorpus() const {
    303   size_t Res = 0;
    304   for (auto &X : Corpus)
    305     Res = std::max(Res, X.size());
    306   return Res;
    307 }
    308 
    309 void Fuzzer::SetMaxLen(size_t MaxLen) {
    310   assert(Options.MaxLen == 0); // Can only reset MaxLen from 0 to non-0.
    311   assert(MaxLen);
    312   Options.MaxLen = MaxLen;
    313   Printf("INFO: -max_len is not provided, using %zd\n", Options.MaxLen);
    314 }
    315 
    316 
    317 void Fuzzer::RereadOutputCorpus(size_t MaxSize) {
    318   if (Options.OutputCorpus.empty())
    319     return;
    320   std::vector<Unit> AdditionalCorpus;
    321   ReadDirToVectorOfUnits(Options.OutputCorpus.c_str(), &AdditionalCorpus,
    322                          &EpochOfLastReadOfOutputCorpus, MaxSize);
    323   if (Corpus.empty()) {
    324     Corpus = AdditionalCorpus;
    325     return;
    326   }
    327   if (!Options.Reload)
    328     return;
    329   if (Options.Verbosity >= 2)
    330     Printf("Reload: read %zd new units.\n", AdditionalCorpus.size());
    331   for (auto &X : AdditionalCorpus) {
    332     if (X.size() > MaxSize)
    333       X.resize(MaxSize);
    334     if (UnitHashesAddedToCorpus.insert(Hash(X)).second) {
    335       if (RunOne(X)) {
    336         Corpus.push_back(X);
    337         UpdateCorpusDistribution();
    338         PrintStats("RELOAD");
    339       }
    340     }
    341   }
    342 }
    343 
    344 void Fuzzer::ShuffleCorpus(UnitVector *V) {
    345   std::random_shuffle(V->begin(), V->end(), MD.GetRand());
    346   if (Options.PreferSmall)
    347     std::stable_sort(V->begin(), V->end(), [](const Unit &A, const Unit &B) {
    348       return A.size() < B.size();
    349     });
    350 }
    351 
    352 // Tries random prefixes of corpus items.
    353 void Fuzzer::TruncateUnits(std::vector<Unit> *NewCorpus) {
    354   std::vector<double> Fractions = {0.25, 0.5, 0.75, 1.0};
    355 
    356   size_t TruncInputs = 0;
    357   for (double Fraction : Fractions) {
    358     for (const auto &U : Corpus) {
    359       uint64_t S = MD.GetRand()(U.size() * Fraction);
    360       if (!S || !RunOne(U.data(), S))
    361         continue;
    362       TruncInputs++;
    363       Unit U1(U.begin(), U.begin() + S);
    364       NewCorpus->push_back(U1);
    365     }
    366   }
    367   if (TruncInputs)
    368     Printf("\tINFO   TRUNC %zd units added to in-memory corpus\n", TruncInputs);
    369 }
    370 
    371 void Fuzzer::ShuffleAndMinimize() {
    372   PrintStats("READ  ");
    373   std::vector<Unit> NewCorpus;
    374   if (Options.ShuffleAtStartUp)
    375     ShuffleCorpus(&Corpus);
    376 
    377   if (Options.TruncateUnits) {
    378     ResetCoverage();
    379     TruncateUnits(&NewCorpus);
    380     ResetCoverage();
    381   }
    382 
    383   for (const auto &U : Corpus) {
    384     bool NewCoverage = RunOne(U);
    385     if (!Options.PruneCorpus || NewCoverage) {
    386       NewCorpus.push_back(U);
    387       if (Options.Verbosity >= 2)
    388         Printf("NEW0: %zd L %zd\n", MaxCoverage.BlockCoverage, U.size());
    389     }
    390     TryDetectingAMemoryLeak(U.data(), U.size(),
    391                             /*DuringInitialCorpusExecution*/ true);
    392   }
    393   Corpus = NewCorpus;
    394   UpdateCorpusDistribution();
    395   for (auto &X : Corpus)
    396     UnitHashesAddedToCorpus.insert(Hash(X));
    397   PrintStats("INITED");
    398   if (Corpus.empty()) {
    399     Printf("ERROR: no interesting inputs were found. "
    400            "Is the code instrumented for coverage? Exiting.\n");
    401     exit(1);
    402   }
    403 }
    404 
    405 bool Fuzzer::UpdateMaxCoverage() {
    406   uintptr_t PrevBufferLen = MaxCoverage.PcBufferLen;
    407   bool Res = CoverageController::RecordMax(Options, &MaxCoverage);
    408 
    409   if (Options.PrintNewCovPcs && PrevBufferLen != MaxCoverage.PcBufferLen) {
    410     uintptr_t *CoverageBuf;
    411     EF->__sanitizer_get_coverage_pc_buffer(&CoverageBuf);
    412     assert(CoverageBuf);
    413     for (size_t I = PrevBufferLen; I < MaxCoverage.PcBufferLen; ++I) {
    414       Printf("%p\n", CoverageBuf[I]);
    415     }
    416   }
    417 
    418   return Res;
    419 }
    420 
    421 bool Fuzzer::RunOne(const uint8_t *Data, size_t Size) {
    422   TotalNumberOfRuns++;
    423 
    424   // TODO(aizatsky): this Reset call seems to be not needed.
    425   CoverageController::ResetCounters(Options);
    426   ExecuteCallback(Data, Size);
    427   bool Res = UpdateMaxCoverage();
    428 
    429   auto UnitStopTime = system_clock::now();
    430   auto TimeOfUnit =
    431       duration_cast<seconds>(UnitStopTime - UnitStartTime).count();
    432   if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&
    433       secondsSinceProcessStartUp() >= 2)
    434     PrintStats("pulse ");
    435   if (TimeOfUnit > TimeOfLongestUnitInSeconds &&
    436       TimeOfUnit >= Options.ReportSlowUnits) {
    437     TimeOfLongestUnitInSeconds = TimeOfUnit;
    438     Printf("Slowest unit: %zd s:\n", TimeOfLongestUnitInSeconds);
    439     WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-");
    440   }
    441   return Res;
    442 }
    443 
    444 void Fuzzer::RunOneAndUpdateCorpus(const uint8_t *Data, size_t Size) {
    445   if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
    446     return;
    447   if (RunOne(Data, Size))
    448     ReportNewCoverage({Data, Data + Size});
    449 }
    450 
    451 size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {
    452   assert(InFuzzingThread());
    453   *Data = CurrentUnitData;
    454   return CurrentUnitSize;
    455 }
    456 
    457 void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
    458   assert(InFuzzingThread());
    459   LazyAllocateCurrentUnitData();
    460   UnitStartTime = system_clock::now();
    461   // We copy the contents of Unit into a separate heap buffer
    462   // so that we reliably find buffer overflows in it.
    463   std::unique_ptr<uint8_t[]> DataCopy(new uint8_t[Size]);
    464   memcpy(DataCopy.get(), Data, Size);
    465   if (CurrentUnitData && CurrentUnitData != Data)
    466     memcpy(CurrentUnitData, Data, Size);
    467   AssignTaintLabels(DataCopy.get(), Size);
    468   CurrentUnitSize = Size;
    469   AllocTracer.Start();
    470   int Res = CB(DataCopy.get(), Size);
    471   (void)Res;
    472   HasMoreMallocsThanFrees = AllocTracer.Stop();
    473   CurrentUnitSize = 0;
    474   assert(Res == 0);
    475 }
    476 
    477 std::string Fuzzer::Coverage::DebugString() const {
    478   std::string Result =
    479       std::string("Coverage{") + "BlockCoverage=" +
    480       std::to_string(BlockCoverage) + " CallerCalleeCoverage=" +
    481       std::to_string(CallerCalleeCoverage) + " CounterBitmapBits=" +
    482       std::to_string(CounterBitmapBits) + " PcMapBits=" +
    483       std::to_string(PcMapBits) + "}";
    484   return Result;
    485 }
    486 
    487 void Fuzzer::WriteToOutputCorpus(const Unit &U) {
    488   if (Options.OnlyASCII)
    489     assert(IsASCII(U));
    490   if (Options.OutputCorpus.empty())
    491     return;
    492   std::string Path = DirPlusFile(Options.OutputCorpus, Hash(U));
    493   WriteToFile(U, Path);
    494   if (Options.Verbosity >= 2)
    495     Printf("Written to %s\n", Path.c_str());
    496 }
    497 
    498 void Fuzzer::WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix) {
    499   if (!Options.SaveArtifacts)
    500     return;
    501   std::string Path = Options.ArtifactPrefix + Prefix + Hash(U);
    502   if (!Options.ExactArtifactPath.empty())
    503     Path = Options.ExactArtifactPath; // Overrides ArtifactPrefix.
    504   WriteToFile(U, Path);
    505   Printf("artifact_prefix='%s'; Test unit written to %s\n",
    506          Options.ArtifactPrefix.c_str(), Path.c_str());
    507   if (U.size() <= kMaxUnitSizeToPrint)
    508     Printf("Base64: %s\n", Base64(U).c_str());
    509 }
    510 
    511 void Fuzzer::SaveCorpus() {
    512   if (Options.OutputCorpus.empty())
    513     return;
    514   for (const auto &U : Corpus)
    515     WriteToFile(U, DirPlusFile(Options.OutputCorpus, Hash(U)));
    516   if (Options.Verbosity)
    517     Printf("Written corpus of %zd files to %s\n", Corpus.size(),
    518            Options.OutputCorpus.c_str());
    519 }
    520 
    521 void Fuzzer::PrintStatusForNewUnit(const Unit &U) {
    522   if (!Options.PrintNEW)
    523     return;
    524   PrintStats("NEW   ", "");
    525   if (Options.Verbosity) {
    526     Printf(" L: %zd ", U.size());
    527     MD.PrintMutationSequence();
    528     Printf("\n");
    529   }
    530 }
    531 
    532 void Fuzzer::ReportNewCoverage(const Unit &U) {
    533   Corpus.push_back(U);
    534   UpdateCorpusDistribution();
    535   UnitHashesAddedToCorpus.insert(Hash(U));
    536   MD.RecordSuccessfulMutationSequence();
    537   PrintStatusForNewUnit(U);
    538   WriteToOutputCorpus(U);
    539   NumberOfNewUnitsAdded++;
    540 }
    541 
    542 // Finds minimal number of units in 'Extra' that add coverage to 'Initial'.
    543 // We do it by actually executing the units, sometimes more than once,
    544 // because we may be using different coverage-like signals and the only
    545 // common thing between them is that we can say "this unit found new stuff".
    546 UnitVector Fuzzer::FindExtraUnits(const UnitVector &Initial,
    547                                   const UnitVector &Extra) {
    548   UnitVector Res = Extra;
    549   size_t OldSize = Res.size();
    550   for (int Iter = 0; Iter < 10; Iter++) {
    551     ShuffleCorpus(&Res);
    552     ResetCoverage();
    553 
    554     for (auto &U : Initial)
    555       RunOne(U);
    556 
    557     Corpus.clear();
    558     for (auto &U : Res)
    559       if (RunOne(U))
    560         Corpus.push_back(U);
    561 
    562     char Stat[7] = "MIN   ";
    563     Stat[3] = '0' + Iter;
    564     PrintStats(Stat);
    565 
    566     size_t NewSize = Corpus.size();
    567     assert(NewSize <= OldSize);
    568     Res.swap(Corpus);
    569 
    570     if (NewSize + 5 >= OldSize)
    571       break;
    572     OldSize = NewSize;
    573   }
    574   return Res;
    575 }
    576 
    577 void Fuzzer::Merge(const std::vector<std::string> &Corpora) {
    578   if (Corpora.size() <= 1) {
    579     Printf("Merge requires two or more corpus dirs\n");
    580     return;
    581   }
    582   std::vector<std::string> ExtraCorpora(Corpora.begin() + 1, Corpora.end());
    583 
    584   assert(Options.MaxLen > 0);
    585   UnitVector Initial, Extra;
    586   ReadDirToVectorOfUnits(Corpora[0].c_str(), &Initial, nullptr, Options.MaxLen);
    587   for (auto &C : ExtraCorpora)
    588     ReadDirToVectorOfUnits(C.c_str(), &Extra, nullptr, Options.MaxLen);
    589 
    590   if (!Initial.empty()) {
    591     Printf("=== Minimizing the initial corpus of %zd units\n", Initial.size());
    592     Initial = FindExtraUnits({}, Initial);
    593   }
    594 
    595   Printf("=== Merging extra %zd units\n", Extra.size());
    596   auto Res = FindExtraUnits(Initial, Extra);
    597 
    598   for (auto &U: Res)
    599     WriteToOutputCorpus(U);
    600 
    601   Printf("=== Merge: written %zd units\n", Res.size());
    602 }
    603 
    604 // Tries detecting a memory leak on the particular input that we have just
    605 // executed before calling this function.
    606 void Fuzzer::TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
    607                                      bool DuringInitialCorpusExecution) {
    608   if (!HasMoreMallocsThanFrees) return;  // mallocs==frees, a leak is unlikely.
    609   if (!Options.DetectLeaks) return;
    610   if (!&(EF->__lsan_enable) || !&(EF->__lsan_disable) ||
    611       !(EF->__lsan_do_recoverable_leak_check))
    612     return;  // No lsan.
    613   // Run the target once again, but with lsan disabled so that if there is
    614   // a real leak we do not report it twice.
    615   EF->__lsan_disable();
    616   RunOne(Data, Size);
    617   EF->__lsan_enable();
    618   if (!HasMoreMallocsThanFrees) return;  // a leak is unlikely.
    619   if (NumberOfLeakDetectionAttempts++ > 1000) {
    620     Options.DetectLeaks = false;
    621     Printf("INFO: libFuzzer disabled leak detection after every mutation.\n"
    622            "      Most likely the target function accumulates allocated\n"
    623            "      memory in a global state w/o actually leaking it.\n"
    624            "      If LeakSanitizer is enabled in this process it will still\n"
    625            "      run on the process shutdown.\n");
    626     return;
    627   }
    628   // Now perform the actual lsan pass. This is expensive and we must ensure
    629   // we don't call it too often.
    630   if (EF->__lsan_do_recoverable_leak_check()) { // Leak is found, report it.
    631     if (DuringInitialCorpusExecution)
    632       Printf("\nINFO: a leak has been found in the initial corpus.\n\n");
    633     Printf("INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.\n\n");
    634     CurrentUnitSize = Size;
    635     DumpCurrentUnit("leak-");
    636     PrintFinalStats();
    637     _Exit(Options.ErrorExitCode);  // not exit() to disable lsan further on.
    638   }
    639 }
    640 
    641 void Fuzzer::MutateAndTestOne() {
    642   LazyAllocateCurrentUnitData();
    643   MD.StartMutationSequence();
    644 
    645   auto &U = ChooseUnitToMutate();
    646   assert(CurrentUnitData);
    647   size_t Size = U.size();
    648   assert(Size <= Options.MaxLen && "Oversized Unit");
    649   memcpy(CurrentUnitData, U.data(), Size);
    650 
    651   for (int i = 0; i < Options.MutateDepth; i++) {
    652     size_t NewSize = 0;
    653     NewSize = MD.Mutate(CurrentUnitData, Size, Options.MaxLen);
    654     assert(NewSize > 0 && "Mutator returned empty unit");
    655     assert(NewSize <= Options.MaxLen &&
    656            "Mutator return overisized unit");
    657     Size = NewSize;
    658     if (i == 0)
    659       StartTraceRecording();
    660     RunOneAndUpdateCorpus(CurrentUnitData, Size);
    661     StopTraceRecording();
    662     TryDetectingAMemoryLeak(CurrentUnitData, Size,
    663                             /*DuringInitialCorpusExecution*/ false);
    664   }
    665 }
    666 
    667 // Returns an index of random unit from the corpus to mutate.
    668 // Hypothesis: units added to the corpus last are more likely to be interesting.
    669 // This function gives more weight to the more recent units.
    670 size_t Fuzzer::ChooseUnitIdxToMutate() {
    671   size_t Idx =
    672       static_cast<size_t>(CorpusDistribution(MD.GetRand().Get_mt19937()));
    673   assert(Idx < Corpus.size());
    674   return Idx;
    675 }
    676 
    677 void Fuzzer::ResetCoverage() {
    678   CoverageController::Reset();
    679   MaxCoverage.Reset();
    680   CoverageController::Prepare(Options, &MaxCoverage);
    681 }
    682 
    683 // Experimental search heuristic: drilling.
    684 // - Read, shuffle, execute and minimize the corpus.
    685 // - Choose one random unit.
    686 // - Reset the coverage.
    687 // - Start fuzzing as if the chosen unit was the only element of the corpus.
    688 // - When done, reset the coverage again.
    689 // - Merge the newly created corpus into the original one.
    690 void Fuzzer::Drill() {
    691   // The corpus is already read, shuffled, and minimized.
    692   assert(!Corpus.empty());
    693   Options.PrintNEW = false; // Don't print NEW status lines when drilling.
    694 
    695   Unit U = ChooseUnitToMutate();
    696 
    697   ResetCoverage();
    698 
    699   std::vector<Unit> SavedCorpus;
    700   SavedCorpus.swap(Corpus);
    701   Corpus.push_back(U);
    702   UpdateCorpusDistribution();
    703   assert(Corpus.size() == 1);
    704   RunOne(U);
    705   PrintStats("DRILL ");
    706   std::string SavedOutputCorpusPath; // Don't write new units while drilling.
    707   SavedOutputCorpusPath.swap(Options.OutputCorpus);
    708   Loop();
    709 
    710   ResetCoverage();
    711 
    712   PrintStats("REINIT");
    713   SavedOutputCorpusPath.swap(Options.OutputCorpus);
    714   for (auto &U : SavedCorpus)
    715     RunOne(U);
    716   PrintStats("MERGE ");
    717   Options.PrintNEW = true;
    718   size_t NumMerged = 0;
    719   for (auto &U : Corpus) {
    720     if (RunOne(U)) {
    721       PrintStatusForNewUnit(U);
    722       NumMerged++;
    723       WriteToOutputCorpus(U);
    724     }
    725   }
    726   PrintStats("MERGED");
    727   if (NumMerged && Options.Verbosity)
    728     Printf("Drilling discovered %zd new units\n", NumMerged);
    729 }
    730 
    731 void Fuzzer::Loop() {
    732   system_clock::time_point LastCorpusReload = system_clock::now();
    733   if (Options.DoCrossOver)
    734     MD.SetCorpus(&Corpus);
    735   while (true) {
    736     auto Now = system_clock::now();
    737     if (duration_cast<seconds>(Now - LastCorpusReload).count()) {
    738       RereadOutputCorpus(Options.MaxLen);
    739       LastCorpusReload = Now;
    740     }
    741     if (TotalNumberOfRuns >= Options.MaxNumberOfRuns)
    742       break;
    743     if (Options.MaxTotalTimeSec > 0 &&
    744         secondsSinceProcessStartUp() >
    745             static_cast<size_t>(Options.MaxTotalTimeSec))
    746       break;
    747     // Perform several mutations and runs.
    748     MutateAndTestOne();
    749   }
    750 
    751   PrintStats("DONE  ", "\n");
    752   MD.PrintRecommendedDictionary();
    753 }
    754 
    755 void Fuzzer::UpdateCorpusDistribution() {
    756   size_t N = Corpus.size();
    757   std::vector<double> Intervals(N + 1);
    758   std::vector<double> Weights(N);
    759   std::iota(Intervals.begin(), Intervals.end(), 0);
    760   std::iota(Weights.begin(), Weights.end(), 1);
    761   CorpusDistribution = std::piecewise_constant_distribution<double>(
    762       Intervals.begin(), Intervals.end(), Weights.begin());
    763 }
    764 
    765 } // namespace fuzzer
    766 
    767 extern "C" {
    768 
    769 size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
    770   assert(fuzzer::F);
    771   return fuzzer::F->GetMD().DefaultMutate(Data, Size, MaxSize);
    772 }
    773 }  // extern "C"
    774