Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Released YYYY-MM-DD.

### Changed

* TODO (or remove section if none)
* Updated to `libFuzzer` commit `a47b42eb9f9b` (`release/22.x`).

### Deprecated

Expand Down
1 change: 1 addition & 0 deletions libfuzzer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ if(OS_NAME MATCHES "Android|Linux|Fuchsia" AND
CFLAGS ${TARGET_CFLAGS}
CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON
-DCMAKE_POSITION_INDEPENDENT_CODE=ON
-DRUNTIMES_EXECUTE_ONLY_CODE=${RUNTIMES_EXECUTE_ONLY_CODE}
-DLIBCXXABI_ENABLE_EXCEPTIONS=OFF
-DLIBCXX_ABI_NAMESPACE=__Fuzzer
-DLIBCXX_ENABLE_EXCEPTIONS=OFF)
Expand Down
7 changes: 4 additions & 3 deletions libfuzzer/FuzzerCorpus.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct InputInfo {
size_t Tmp = 0; // Used by ValidateFeatureSet.
// Stats.
size_t NumExecutedMutations = 0;
size_t NumSuccessfullMutations = 0;
size_t NumSuccessfulMutations = 0;
bool NeverReduce = false;
bool MayDeleteFile = false;
bool Reduced = false;
Expand Down Expand Up @@ -328,15 +328,16 @@ class InputCorpus {
const auto &II = *Inputs[i];
Printf(" [% 3zd %s] sz: % 5zd runs: % 5zd succ: % 5zd focus: %d\n", i,
Sha1ToString(II.Sha1).c_str(), II.U.size(),
II.NumExecutedMutations, II.NumSuccessfullMutations,
II.NumExecutedMutations, II.NumSuccessfulMutations,
II.HasFocusFunction);
}
}

void PrintFeatureSet() {
for (size_t i = 0; i < kFeatureSetSize; i++) {
if(size_t Sz = GetFeature(i))
Printf("[%zd: id %zd sz%zd] ", i, SmallestElementPerFeature[i], Sz);
Printf("[%zd: id %zd sz%zd] ", i, (size_t)SmallestElementPerFeature[i],
Sz);
}
Printf("\n\t");
for (size_t i = 0; i < Inputs.size(); i++)
Expand Down
2 changes: 0 additions & 2 deletions libfuzzer/FuzzerDataFlowTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,6 @@ int CollectDataFlow(const std::string &DFTBinary, const std::string &DirPath,
// we then request tags in [0,Size/2) and [Size/2, Size), and so on.
// Function number => DFT.
auto OutPath = DirPlusFile(DirPath, Hash(FileToVector(F.File)));
std::unordered_map<size_t, std::vector<uint8_t>> DFTMap;
std::unordered_set<std::string> Cov;
Command Cmd;
Cmd.addArgument(DFTBinary);
Cmd.addArgument(F.File);
Expand Down
20 changes: 14 additions & 6 deletions libfuzzer/FuzzerDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@
#include <chrono>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <functional>
#include <mutex>
#include <string>
#include <thread>
#include <fstream>

// This function should be present in the libFuzzer so that the client
// binary can test for its existence.
Expand Down Expand Up @@ -162,13 +163,13 @@ static bool ParseOneFlag(const char *Param) {
auto Val = MyStol(Str);
*FlagDescriptions[F].IntFlag = static_cast<int>(Val);
if (Flags.verbosity >= 2)
Printf("Flag: %s %d\n", Name, Val);
Printf("Flag: %s %d\n", Name, (int)Val);
return true;
} else if (FlagDescriptions[F].UIntFlag) {
auto Val = std::stoul(Str);
*FlagDescriptions[F].UIntFlag = static_cast<unsigned int>(Val);
if (Flags.verbosity >= 2)
Printf("Flag: %s %u\n", Name, Val);
Printf("Flag: %s %u\n", Name, (uint32_t)Val);
return true;
} else if (FlagDescriptions[F].StrFlag) {
*FlagDescriptions[F].StrFlag = Str;
Expand Down Expand Up @@ -305,6 +306,11 @@ static int RunInMultipleProcesses(const std::vector<std::string> &Args,
return HasErrors ? 1 : 0;
}

void StartRssThread(Fuzzer *F, size_t RssLimitMb);

// Fuchsia needs to do some book checking before starting the RssThread,
// so it has its own implementation.
#if !LIBFUZZER_FUCHSIA
static void RssThread(Fuzzer *F, size_t RssLimitMb) {
while (true) {
SleepSeconds(1);
Expand All @@ -314,12 +320,13 @@ static void RssThread(Fuzzer *F, size_t RssLimitMb) {
}
}

static void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
if (!RssLimitMb)
return;
std::thread T(RssThread, F, RssLimitMb);
T.detach();
}
#endif

int RunOneTest(Fuzzer *F, const char *InputFilePath, size_t MaxLen) {
Unit U = FileToVector(InputFilePath);
Expand Down Expand Up @@ -602,7 +609,7 @@ int AnalyzeDictionary(Fuzzer *F, const std::vector<Unit> &Dict,
return 0;
}

std::vector<std::string> ParseSeedInuts(const char *seed_inputs) {
std::vector<std::string> ParseSeedInputs(const char *seed_inputs) {
// Parse -seed_inputs=file1,file2,... or -seed_inputs=@seed_inputs_file
std::vector<std::string> Files;
if (!seed_inputs) return Files;
Expand Down Expand Up @@ -833,6 +840,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Options.HandleInt = Flags.handle_int;
Options.HandleSegv = Flags.handle_segv;
Options.HandleTerm = Flags.handle_term;
Options.HandleTrap = Flags.handle_trap;
Options.HandleXfsz = Flags.handle_xfsz;
Options.HandleUsr1 = Flags.handle_usr1;
Options.HandleUsr2 = Flags.handle_usr2;
Expand Down Expand Up @@ -911,7 +919,7 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
exit(0);
}

auto CorporaFiles = ReadCorpora(*Inputs, ParseSeedInuts(Flags.seed_inputs));
auto CorporaFiles = ReadCorpora(*Inputs, ParseSeedInputs(Flags.seed_inputs));
F->Loop(CorporaFiles);

if (Flags.verbosity)
Expand Down
2 changes: 1 addition & 1 deletion libfuzzer/FuzzerExtFunctionsWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ using namespace fuzzer;
#define WIN_SYM_PREFIX
#endif

// Declare external functions as having alternativenames, so that we can
// Declare external functions as having alternative names, so that we can
// determine if they are not defined.
#define EXTERNAL_FUNC(Name, Default) \
__pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \
Expand Down
1 change: 1 addition & 0 deletions libfuzzer/FuzzerFlags.def
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ FUZZER_FLAG_INT(handle_ill, 1, "If 1, try to intercept SIGILL.")
FUZZER_FLAG_INT(handle_fpe, 1, "If 1, try to intercept SIGFPE.")
FUZZER_FLAG_INT(handle_int, 1, "If 1, try to intercept SIGINT.")
FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.")
FUZZER_FLAG_INT(handle_trap, 1, "If 1, try to intercept SIGTRAP.")
FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.")
FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.")
FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.")
Expand Down
1 change: 1 addition & 0 deletions libfuzzer/FuzzerIOPosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "FuzzerExtFunctions.h"
#include "FuzzerIO.h"
#include <cerrno>
#include <cstdarg>
#include <cstdio>
#include <dirent.h>
Expand Down
12 changes: 6 additions & 6 deletions libfuzzer/FuzzerLoop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ void FreeHook(const volatile void *ptr) {
void Fuzzer::HandleMalloc(size_t Size) {
if (!Options.MallocLimitMb || (Size >> 20) < (size_t)Options.MallocLimitMb)
return;
Printf("==%d== ERROR: libFuzzer: out-of-memory (malloc(%zd))\n", GetPid(),
Size);
Printf("==%d== ERROR: libFuzzer: out-of-memory (malloc(%zd))\n",
(int)GetPid(), Size);
Printf(" To change the out-of-memory limit use -rss_limit_mb=<N>\n\n");
PrintStackTrace();
DumpCurrentUnit("oom-");
Expand Down Expand Up @@ -448,9 +448,9 @@ void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) {
if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1)) &&
secondsSinceProcessStartUp() >= 2)
PrintStats("pulse ");
auto Threshhold =
auto Threshold =
static_cast<long>(static_cast<double>(TimeOfLongestUnitInSeconds) * 1.1);
if (TimeOfUnit > Threshhold && TimeOfUnit >= Options.ReportSlowUnits) {
if (TimeOfUnit > Threshold && TimeOfUnit >= Options.ReportSlowUnits) {
TimeOfLongestUnitInSeconds = TimeOfUnit;
Printf("Slowest unit: %ld s:\n", TimeOfLongestUnitInSeconds);
WriteUnitToFileWithPrefix({Data, Data + Size}, "slow-unit-");
Expand Down Expand Up @@ -568,7 +568,7 @@ size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const {

void Fuzzer::CrashOnOverwrittenData() {
Printf("==%d== ERROR: libFuzzer: fuzz target overwrites its const input\n",
GetPid());
(int)GetPid());
PrintStackTrace();
Printf("SUMMARY: libFuzzer: overwrites-const-input\n");
DumpCurrentUnit("crash-");
Expand Down Expand Up @@ -666,7 +666,7 @@ void Fuzzer::PrintStatusForNewUnit(const Unit &U, const char *Text) {
}

void Fuzzer::ReportNewCoverage(InputInfo *II, const Unit &U) {
II->NumSuccessfullMutations++;
II->NumSuccessfulMutations++;
MD.RecordSuccessfulMutationSequence();
PrintStatusForNewUnit(U, II->Reduced ? "REDUCE" : "NEW ");
WriteToOutputCorpus(U);
Expand Down
8 changes: 4 additions & 4 deletions libfuzzer/FuzzerMutate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ size_t MutationDispatcher::Mutate_CustomCrossOver(uint8_t *Data, size_t Size,

if (!NewSize)
return 0;
assert(NewSize <= MaxSize && "CustomCrossOver returned overisized unit");
assert(NewSize <= MaxSize && "CustomCrossOver returned oversized unit");
memcpy(Data, U.data(), NewSize);
return NewSize;
}
Expand Down Expand Up @@ -413,9 +413,9 @@ size_t ChangeBinaryInteger(uint8_t *Data, size_t Size, Random &Rand) {
T Add = static_cast<T>(Rand(21));
Add -= 10;
if (Rand.RandBool())
Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endiannes.
Val = Bswap(T(Bswap(Val) + Add)); // Add assuming different endianness.
else
Val = Val + Add; // Add assuming current endiannes.
Val = Val + Add; // Add assuming current endianness.
if (Add == 0 || Rand.RandBool()) // Maybe negate.
Val = -Val;
}
Expand Down Expand Up @@ -463,7 +463,7 @@ size_t MutationDispatcher::Mutate_CrossOver(uint8_t *Data, size_t Size,
default: assert(0);
}
assert(NewSize > 0 && "CrossOver returned empty unit");
assert(NewSize <= MaxSize && "CrossOver returned overisized unit");
assert(NewSize <= MaxSize && "CrossOver returned oversized unit");
return NewSize;
}

Expand Down
1 change: 1 addition & 0 deletions libfuzzer/FuzzerOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct FuzzingOptions {
bool HandleInt = false;
bool HandleSegv = false;
bool HandleTerm = false;
bool HandleTrap = false;
bool HandleXfsz = false;
bool HandleUsr1 = false;
bool HandleUsr2 = false;
Expand Down
1 change: 1 addition & 0 deletions libfuzzer/FuzzerRandom.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#ifndef LLVM_FUZZER_RANDOM_H
#define LLVM_FUZZER_RANDOM_H

#include <cmath>
#include <random>

namespace fuzzer {
Expand Down
3 changes: 3 additions & 0 deletions libfuzzer/FuzzerTracePC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ void TracePC::HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop) {
}

void TracePC::HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop) {
if (Start == Stop) {
return;
}
const PCTableEntry *B = reinterpret_cast<const PCTableEntry *>(Start);
const PCTableEntry *E = reinterpret_cast<const PCTableEntry *>(Stop);
if (NumPCTables && ModulePCTable[NumPCTables - 1].Start == B) return;
Expand Down
62 changes: 58 additions & 4 deletions libfuzzer/FuzzerUtilFuchsia.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ void ExitOnErr(zx_status_t Status, const char *Syscall) {
}

void AlarmHandler(int Seconds) {
// Signal the alarm thread started.
ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0),
"_zx_object_signal alarm");
while (true) {
SleepSeconds(Seconds);
Fuzzer::StaticAlarmCallback();
Expand Down Expand Up @@ -282,6 +285,7 @@ void CrashHandler() {
Self, ZX_EXCEPTION_CHANNEL_DEBUGGER, &Channel.Handle),
"_zx_task_create_exception_channel");

// Signal the crash thread started.
ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0),
"_zx_object_signal");

Expand Down Expand Up @@ -385,10 +389,49 @@ void StopSignalHandler() {
_zx_handle_close(SignalHandlerEvent);
}

void RssThread(Fuzzer *F, size_t RssLimitMb) {
// Signal the rss thread started.
//
// We must wait for this thread to start because we could accidentally suspend
// it while the crash handler is attempting to handle the
// ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by the
// lsan machinery, then there's no way for this thread to indicate it's
// suspended because it's blocked on waiting for the exception to be handled.
ExitOnErr(_zx_object_signal(SignalHandlerEvent, 0, ZX_USER_SIGNAL_0),
"_zx_object_signal rss");
while (true) {
SleepSeconds(1);
size_t Peak = GetPeakRSSMb();
if (Peak > RssLimitMb)
F->RssLimitCallback();
}
}

} // namespace

void StartRssThread(Fuzzer *F, size_t RssLimitMb) {
// Set up the crash handler and wait until it is ready before proceeding.
assert(SignalHandlerEvent == ZX_HANDLE_INVALID);
ExitOnErr(_zx_event_create(0, &SignalHandlerEvent), "_zx_event_create");

if (!RssLimitMb)
return;
std::thread T(RssThread, F, RssLimitMb);
T.detach();

// Wait for the rss thread to start.
ExitOnErr(_zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0,
ZX_TIME_INFINITE, nullptr),
"_zx_object_wait_one rss");
ExitOnErr(_zx_object_signal(SignalHandlerEvent, ZX_USER_SIGNAL_0, 0),
"_zx_object_signal rss clear");
}

// Platform specific functions.
void SetSignalHandler(const FuzzingOptions &Options) {
assert(SignalHandlerEvent != ZX_HANDLE_INVALID &&
"This should've been setup by StartRssThread.");

// Make sure information from libFuzzer and the sanitizers are easy to
// reassemble. `__sanitizer_log_write` has the added benefit of ensuring the
// DSO map is always available for the symbolizer.
Expand All @@ -404,18 +447,29 @@ void SetSignalHandler(const FuzzingOptions &Options) {
if (Options.HandleAlrm && Options.UnitTimeoutSec > 0) {
std::thread T(AlarmHandler, Options.UnitTimeoutSec / 2 + 1);
T.detach();

// Wait for the alarm thread to start.
//
// We must wait for this thread to start because we could accidentally
// suspend it while the crash handler is attempting to handle the
// ZX_EXCP_THREAD_STARTING exception. If the crash handler is suspended by
// the lsan machinery, then there's no way for this thread to indicate it's
// suspended because it's blocked on waiting for the exception to be
// handled.
ExitOnErr(_zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0,
ZX_TIME_INFINITE, nullptr),
"_zx_object_wait_one alarm");
ExitOnErr(_zx_object_signal(SignalHandlerEvent, ZX_USER_SIGNAL_0, 0),
"_zx_object_signal alarm clear");
}

// Options.HandleInt and Options.HandleTerm are not supported on Fuchsia

// Early exit if no crash handler needed.
if (!Options.HandleSegv && !Options.HandleBus && !Options.HandleIll &&
!Options.HandleFpe && !Options.HandleAbrt)
!Options.HandleFpe && !Options.HandleAbrt && !Options.HandleTrap)
return;

// Set up the crash handler and wait until it is ready before proceeding.
ExitOnErr(_zx_event_create(0, &SignalHandlerEvent), "_zx_event_create");

SignalHandler = std::thread(CrashHandler);
zx_status_t Status = _zx_object_wait_one(SignalHandlerEvent, ZX_USER_SIGNAL_0,
ZX_TIME_INFINITE, nullptr);
Expand Down
2 changes: 2 additions & 0 deletions libfuzzer/FuzzerUtilPosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ void SetSignalHandler(const FuzzingOptions& Options) {
SetSigaction(SIGILL, CrashHandler);
if (Options.HandleFpe)
SetSigaction(SIGFPE, CrashHandler);
if (Options.HandleTrap)
SetSigaction(SIGTRAP, CrashHandler);
if (Options.HandleXfsz)
SetSigaction(SIGXFSZ, FileSizeExceedHandler);
if (Options.HandleUsr1)
Expand Down
2 changes: 1 addition & 1 deletion libfuzzer/FuzzerUtilWindows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// clang-format off
#include <windows.h>
// These must be included after windows.h.
// archicture need to be set before including
// architecture need to be set before including
// libloaderapi
#include <libloaderapi.h>
#include <stringapiset.h>
Expand Down
Loading