2015-01-29 17:58:29 +01:00
|
|
|
//===- 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.
|
|
|
|
//===----------------------------------------------------------------------===//
|
2015-08-10 18:37:40 +02:00
|
|
|
|
|
|
|
#ifndef LLVM_FUZZER_INTERNAL_H
|
|
|
|
#define LLVM_FUZZER_INTERNAL_H
|
|
|
|
|
2016-02-13 04:37:24 +01:00
|
|
|
#include <algorithm>
|
2016-05-27 02:54:15 +02:00
|
|
|
#include <atomic>
|
2015-01-29 17:58:29 +01:00
|
|
|
#include <chrono>
|
2016-01-22 23:28:27 +01:00
|
|
|
#include <climits>
|
2015-01-29 17:58:29 +01:00
|
|
|
#include <cstdlib>
|
2016-01-16 04:53:32 +01:00
|
|
|
#include <string.h>
|
2016-08-24 03:38:42 +02:00
|
|
|
|
2016-09-21 03:50:50 +02:00
|
|
|
#include "FuzzerDefs.h"
|
2016-08-24 03:38:42 +02:00
|
|
|
#include "FuzzerExtFunctions.h"
|
|
|
|
#include "FuzzerInterface.h"
|
2016-09-21 04:05:39 +02:00
|
|
|
#include "FuzzerOptions.h"
|
2016-08-24 03:38:42 +02:00
|
|
|
#include "FuzzerValueBitMap.h"
|
|
|
|
|
2015-01-29 17:58:29 +01:00
|
|
|
namespace fuzzer {
|
2016-05-13 20:04:35 +02:00
|
|
|
|
2015-01-29 17:58:29 +01:00
|
|
|
using namespace std::chrono;
|
2015-05-12 20:51:57 +02:00
|
|
|
|
2016-08-16 21:33:51 +02:00
|
|
|
// See FuzzerTraceState.cpp
|
|
|
|
void EnableValueProfile();
|
2016-09-23 02:22:46 +02:00
|
|
|
bool VPMapMergeFromCurrent(ValueBitMap &M);
|
2016-08-16 21:33:51 +02:00
|
|
|
|
2015-01-29 17:58:29 +01:00
|
|
|
class Fuzzer {
|
2016-01-22 23:28:27 +01:00
|
|
|
public:
|
2016-05-11 01:43:15 +02:00
|
|
|
|
|
|
|
// Aggregates all available coverage measurements.
|
|
|
|
struct Coverage {
|
|
|
|
Coverage() { Reset(); }
|
|
|
|
|
|
|
|
void Reset() {
|
|
|
|
BlockCoverage = 0;
|
|
|
|
CallerCalleeCoverage = 0;
|
|
|
|
CounterBitmapBits = 0;
|
|
|
|
CounterBitmap.clear();
|
2016-08-16 21:33:51 +02:00
|
|
|
VPMap.Reset();
|
2016-09-15 03:30:18 +02:00
|
|
|
TPCMap.Reset();
|
2016-05-11 01:43:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string DebugString() const;
|
|
|
|
|
|
|
|
size_t BlockCoverage;
|
|
|
|
size_t CallerCalleeCoverage;
|
|
|
|
// Precalculated number of bits in CounterBitmap.
|
|
|
|
size_t CounterBitmapBits;
|
|
|
|
std::vector<uint8_t> CounterBitmap;
|
2016-09-15 03:30:18 +02:00
|
|
|
ValueBitMap TPCMap;
|
2016-08-16 21:33:51 +02:00
|
|
|
ValueBitMap VPMap;
|
2016-05-11 01:43:15 +02:00
|
|
|
};
|
|
|
|
|
2016-09-22 00:42:17 +02:00
|
|
|
Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
|
|
|
|
FuzzingOptions Options);
|
2016-08-05 22:09:53 +02:00
|
|
|
~Fuzzer();
|
2015-09-08 19:30:35 +02:00
|
|
|
void Loop();
|
2016-09-21 03:04:43 +02:00
|
|
|
void ShuffleAndMinimize(UnitVector *V);
|
2015-05-11 23:16:27 +02:00
|
|
|
void InitializeTraceState();
|
2016-01-14 00:02:30 +01:00
|
|
|
void AssignTaintLabels(uint8_t *Data, size_t Size);
|
2016-03-12 02:57:04 +01:00
|
|
|
void RereadOutputCorpus(size_t MaxSize);
|
2015-01-29 17:58:29 +01:00
|
|
|
|
2015-02-05 00:42:42 +01:00
|
|
|
size_t secondsSinceProcessStartUp() {
|
|
|
|
return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
|
|
|
|
.count();
|
|
|
|
}
|
2016-02-26 23:42:23 +01:00
|
|
|
size_t execPerSec() {
|
|
|
|
size_t Seconds = secondsSinceProcessStartUp();
|
|
|
|
return Seconds ? TotalNumberOfRuns / Seconds : 0;
|
|
|
|
}
|
2015-02-05 00:42:42 +01:00
|
|
|
|
|
|
|
size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
|
|
|
|
|
2015-03-31 22:13:20 +02:00
|
|
|
static void StaticAlarmCallback();
|
2016-03-01 23:19:21 +01:00
|
|
|
static void StaticCrashSignalCallback();
|
|
|
|
static void StaticInterruptCallback();
|
2015-03-31 22:13:20 +02:00
|
|
|
|
2016-02-13 18:56:51 +01:00
|
|
|
void ExecuteCallback(const uint8_t *Data, size_t Size);
|
2016-05-04 22:44:50 +02:00
|
|
|
bool RunOne(const uint8_t *Data, size_t Size);
|
2015-01-29 17:58:29 +01:00
|
|
|
|
2015-10-24 03:16:40 +02:00
|
|
|
// Merge Corpora[1:] into Corpora[0].
|
|
|
|
void Merge(const std::vector<std::string> &Corpora);
|
2016-03-18 01:23:29 +01:00
|
|
|
// Returns a subset of 'Extra' that adds coverage to 'Initial'.
|
|
|
|
UnitVector FindExtraUnits(const UnitVector &Initial, const UnitVector &Extra);
|
2016-02-13 07:24:18 +01:00
|
|
|
MutationDispatcher &GetMD() { return MD; }
|
2016-02-26 23:42:23 +01:00
|
|
|
void PrintFinalStats();
|
2016-09-23 01:16:36 +02:00
|
|
|
void SetMaxInputLen(size_t MaxInputLen);
|
|
|
|
void SetMaxMutationLen(size_t MaxMutationLen);
|
2016-05-07 01:38:07 +02:00
|
|
|
void RssLimitCallback();
|
2015-10-24 03:16:40 +02:00
|
|
|
|
2016-05-25 01:14:29 +02:00
|
|
|
// Public for tests.
|
|
|
|
void ResetCoverage();
|
|
|
|
|
2016-05-26 23:32:30 +02:00
|
|
|
bool InFuzzingThread() const { return IsMyThread; }
|
2016-05-27 00:17:32 +02:00
|
|
|
size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
|
2016-05-26 23:32:30 +02:00
|
|
|
|
2016-01-22 23:28:27 +01:00
|
|
|
private:
|
2015-03-31 22:13:20 +02:00
|
|
|
void AlarmCallback();
|
2016-03-01 23:19:21 +01:00
|
|
|
void CrashCallback();
|
|
|
|
void InterruptCallback();
|
2015-12-19 03:49:09 +01:00
|
|
|
void MutateAndTestOne();
|
2016-09-22 00:42:17 +02:00
|
|
|
void ReportNewCoverage(InputInfo *II, const Unit &U);
|
2016-08-26 00:35:08 +02:00
|
|
|
void PrintNewPCs();
|
2016-09-15 06:36:45 +02:00
|
|
|
void PrintOneNewPC(uintptr_t PC);
|
2016-02-13 18:56:51 +01:00
|
|
|
bool RunOne(const Unit &U) { return RunOne(U.data(), U.size()); }
|
2015-01-29 17:58:29 +01:00
|
|
|
void WriteToOutputCorpus(const Unit &U);
|
2015-07-23 20:37:22 +02:00
|
|
|
void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
|
2015-10-23 00:56:45 +02:00
|
|
|
void PrintStats(const char *Where, const char *End = "\n");
|
2015-11-12 02:02:01 +01:00
|
|
|
void PrintStatusForNewUnit(const Unit &U);
|
2016-03-18 01:23:29 +01:00
|
|
|
void ShuffleCorpus(UnitVector *V);
|
2016-05-26 22:25:49 +02:00
|
|
|
void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
|
|
|
|
bool DuringInitialCorpusExecution);
|
2016-03-18 01:23:29 +01:00
|
|
|
|
2016-05-11 01:43:15 +02:00
|
|
|
bool UpdateMaxCoverage();
|
2015-10-23 00:50:47 +02:00
|
|
|
|
2015-05-07 23:02:11 +02:00
|
|
|
// Trace-based fuzzing: we run a unit with some kind of tracing
|
|
|
|
// enabled and record potentially useful mutations. Then
|
|
|
|
// We apply these mutations one by one to the unit and run it again.
|
|
|
|
|
|
|
|
// Start tracing; forget all previously proposed mutations.
|
|
|
|
void StartTraceRecording();
|
2016-01-09 04:08:58 +01:00
|
|
|
// Stop tracing.
|
|
|
|
void StopTraceRecording();
|
2015-05-07 23:02:11 +02:00
|
|
|
|
2015-01-29 17:58:29 +01:00
|
|
|
void SetDeathCallback();
|
2015-03-31 22:13:20 +02:00
|
|
|
static void StaticDeathCallback();
|
2016-03-01 23:19:21 +01:00
|
|
|
void DumpCurrentUnit(const char *Prefix);
|
2015-03-31 22:13:20 +02:00
|
|
|
void DeathCallback();
|
2016-01-14 00:46:01 +01:00
|
|
|
|
2016-08-25 03:25:03 +02:00
|
|
|
void ResetEdgeCoverage();
|
2016-09-09 04:38:28 +02:00
|
|
|
void ResetCounters();
|
2016-08-25 03:25:03 +02:00
|
|
|
void PrepareCounters(Fuzzer::Coverage *C);
|
|
|
|
bool RecordMaxCoverage(Fuzzer::Coverage *C);
|
|
|
|
|
2016-09-23 01:16:36 +02:00
|
|
|
void AllocateCurrentUnitData();
|
2016-05-27 02:21:33 +02:00
|
|
|
uint8_t *CurrentUnitData = nullptr;
|
2016-05-27 02:54:15 +02:00
|
|
|
std::atomic<size_t> CurrentUnitSize;
|
2016-08-17 22:45:23 +02:00
|
|
|
uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
|
2015-01-29 17:58:29 +01:00
|
|
|
|
|
|
|
size_t TotalNumberOfRuns = 0;
|
2016-02-26 23:42:23 +01:00
|
|
|
size_t NumberOfNewUnitsAdded = 0;
|
2015-01-29 17:58:29 +01:00
|
|
|
|
2016-04-20 02:24:21 +02:00
|
|
|
bool HasMoreMallocsThanFrees = false;
|
2016-04-27 21:52:34 +02:00
|
|
|
size_t NumberOfLeakDetectionAttempts = 0;
|
2016-04-20 02:24:21 +02:00
|
|
|
|
2016-02-13 04:25:16 +01:00
|
|
|
UserCallback CB;
|
2016-09-22 00:42:17 +02:00
|
|
|
InputCorpus &Corpus;
|
2016-02-13 04:25:16 +01:00
|
|
|
MutationDispatcher &MD;
|
2015-01-29 17:58:29 +01:00
|
|
|
FuzzingOptions Options;
|
2016-09-22 00:42:17 +02:00
|
|
|
|
2015-01-29 17:58:29 +01:00
|
|
|
system_clock::time_point ProcessStartTime = system_clock::now();
|
2016-09-22 03:34:58 +02:00
|
|
|
system_clock::time_point UnitStartTime, UnitStopTime;
|
2015-03-31 01:04:35 +02:00
|
|
|
long TimeOfLongestUnitInSeconds = 0;
|
2015-05-08 23:30:55 +02:00
|
|
|
long EpochOfLastReadOfOutputCorpus = 0;
|
2016-05-11 01:43:15 +02:00
|
|
|
|
|
|
|
// Maximum recorded coverage.
|
|
|
|
Coverage MaxCoverage;
|
2016-08-25 03:25:03 +02:00
|
|
|
|
2016-09-23 01:16:36 +02:00
|
|
|
size_t MaxInputLen = 0;
|
|
|
|
size_t MaxMutationLen = 0;
|
|
|
|
|
2016-08-26 00:35:08 +02:00
|
|
|
// For -print_pcs
|
2016-08-25 03:25:03 +02:00
|
|
|
uintptr_t* PcBuffer = nullptr;
|
|
|
|
size_t PcBufferLen = 0;
|
2016-09-09 04:38:28 +02:00
|
|
|
size_t PcBufferPos = 0, PrevPcBufferPos = 0;
|
2016-05-26 23:32:30 +02:00
|
|
|
|
|
|
|
// Need to know our own thread.
|
|
|
|
static thread_local bool IsMyThread;
|
2016-09-10 02:15:41 +02:00
|
|
|
|
|
|
|
bool InMergeMode = false;
|
2015-01-29 17:58:29 +01:00
|
|
|
};
|
|
|
|
|
2016-01-22 23:28:27 +01:00
|
|
|
}; // namespace fuzzer
|
2015-08-10 18:37:40 +02:00
|
|
|
|
|
|
|
#endif // LLVM_FUZZER_INTERNAL_H
|