llvm-project/compiler-rt/lib/fuzzer/FuzzerInternal.h
Matt Morehouse 43a2296976 libFuzzer: prevent irrelevant strings from leaking into auto-dictionary
This is a fix for bug 37047.

https://bugs.llvm.org/show_bug.cgi?id=37047

Implemented by basically reversing the logic. Previously all strings
were considered, with some operations excluded. Now strings are excluded
by default, and only strings during the CB considered.

Patch By: pdknsk

Differential Revision: https://reviews.llvm.org/D48800

llvm-svn: 337296
2018-07-17 16:12:00 +00:00

180 lines
5.7 KiB
C++

//===- 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.
//===----------------------------------------------------------------------===//
#ifndef LLVM_FUZZER_INTERNAL_H
#define LLVM_FUZZER_INTERNAL_H
#include "FuzzerDataFlowTrace.h"
#include "FuzzerDefs.h"
#include "FuzzerExtFunctions.h"
#include "FuzzerInterface.h"
#include "FuzzerOptions.h"
#include "FuzzerSHA1.h"
#include "FuzzerValueBitMap.h"
#include <algorithm>
#include <atomic>
#include <chrono>
#include <climits>
#include <cstdlib>
#include <string.h>
namespace fuzzer {
using namespace std::chrono;
class Fuzzer {
public:
Fuzzer(UserCallback CB, InputCorpus &Corpus, MutationDispatcher &MD,
FuzzingOptions Options);
~Fuzzer();
void Loop(const Vector<std::string> &CorpusDirs);
void ReadAndExecuteSeedCorpora(const Vector<std::string> &CorpusDirs);
void MinimizeCrashLoop(const Unit &U);
void RereadOutputCorpus(size_t MaxSize);
size_t secondsSinceProcessStartUp() {
return duration_cast<seconds>(system_clock::now() - ProcessStartTime)
.count();
}
bool TimedOut() {
return Options.MaxTotalTimeSec > 0 &&
secondsSinceProcessStartUp() >
static_cast<size_t>(Options.MaxTotalTimeSec);
}
size_t execPerSec() {
size_t Seconds = secondsSinceProcessStartUp();
return Seconds ? TotalNumberOfRuns / Seconds : 0;
}
size_t getTotalNumberOfRuns() { return TotalNumberOfRuns; }
static void StaticAlarmCallback();
static void StaticCrashSignalCallback();
static void StaticExitCallback();
static void StaticInterruptCallback();
static void StaticFileSizeExceedCallback();
static void StaticGracefulExitCallback();
void ExecuteCallback(const uint8_t *Data, size_t Size);
void CheckForUnstableCounters(const uint8_t *Data, size_t Size);
bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
InputInfo *II = nullptr, bool *FoundUniqFeatures = nullptr);
// Merge Corpora[1:] into Corpora[0].
void Merge(const Vector<std::string> &Corpora);
void CrashResistantMerge(const Vector<std::string> &Args,
const Vector<std::string> &Corpora,
const char *CoverageSummaryInputPathOrNull,
const char *CoverageSummaryOutputPathOrNull,
const char *MergeControlFilePathOrNull);
void CrashResistantMergeInternalStep(const std::string &ControlFilePath);
MutationDispatcher &GetMD() { return MD; }
void PrintFinalStats();
void SetMaxInputLen(size_t MaxInputLen);
void SetMaxMutationLen(size_t MaxMutationLen);
void RssLimitCallback();
bool InFuzzingThread() const { return IsMyThread; }
size_t GetCurrentUnitInFuzzingThead(const uint8_t **Data) const;
void TryDetectingAMemoryLeak(const uint8_t *Data, size_t Size,
bool DuringInitialCorpusExecution);
void HandleMalloc(size_t Size);
void AnnounceOutput(const uint8_t *Data, size_t Size);
private:
void AlarmCallback();
void CrashCallback();
void ExitCallback();
void MaybeExitGracefully();
void CrashOnOverwrittenData();
void InterruptCallback();
void MutateAndTestOne();
void PurgeAllocator();
void ReportNewCoverage(InputInfo *II, const Unit &U);
void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size);
void WriteToOutputCorpus(const Unit &U);
void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix);
void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0);
void PrintStatusForNewUnit(const Unit &U, const char *Text);
void CheckExitOnSrcPosOrItem();
static void StaticDeathCallback();
void DumpCurrentUnit(const char *Prefix);
void DeathCallback();
void AllocateCurrentUnitData();
uint8_t *CurrentUnitData = nullptr;
std::atomic<size_t> CurrentUnitSize;
uint8_t BaseSha1[kSHA1NumBytes]; // Checksum of the base unit.
bool GracefulExitRequested = false;
size_t TotalNumberOfRuns = 0;
size_t NumberOfNewUnitsAdded = 0;
size_t LastCorpusUpdateRun = 0;
bool HasMoreMallocsThanFrees = false;
size_t NumberOfLeakDetectionAttempts = 0;
system_clock::time_point LastAllocatorPurgeAttemptTime = system_clock::now();
UserCallback CB;
InputCorpus &Corpus;
MutationDispatcher &MD;
FuzzingOptions Options;
DataFlowTrace DFT;
system_clock::time_point ProcessStartTime = system_clock::now();
system_clock::time_point UnitStartTime, UnitStopTime;
long TimeOfLongestUnitInSeconds = 0;
long EpochOfLastReadOfOutputCorpus = 0;
size_t MaxInputLen = 0;
size_t MaxMutationLen = 0;
size_t TmpMaxMutationLen = 0;
Vector<uint32_t> UniqFeatureSetTmp;
// Need to know our own thread.
static thread_local bool IsMyThread;
};
struct ScopedEnableMsanInterceptorChecks {
ScopedEnableMsanInterceptorChecks() {
if (EF->__msan_scoped_enable_interceptor_checks)
EF->__msan_scoped_enable_interceptor_checks();
}
~ScopedEnableMsanInterceptorChecks() {
if (EF->__msan_scoped_disable_interceptor_checks)
EF->__msan_scoped_disable_interceptor_checks();
}
};
struct ScopedDisableMsanInterceptorChecks {
ScopedDisableMsanInterceptorChecks() {
if (EF->__msan_scoped_disable_interceptor_checks)
EF->__msan_scoped_disable_interceptor_checks();
}
~ScopedDisableMsanInterceptorChecks() {
if (EF->__msan_scoped_enable_interceptor_checks)
EF->__msan_scoped_enable_interceptor_checks();
}
};
} // namespace fuzzer
#endif // LLVM_FUZZER_INTERNAL_H