diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-06 20:13:21 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-06 20:13:21 +0000 |
commit | 7e7b6700743285c0af506ac6299ddf82ebd434b9 (patch) | |
tree | 578d2ea1868b77f3dff145df7f8f3fe73272c09e /lib/Fuzzer | |
parent | 4b570baa7e867c652fa7d690585098278082fae9 (diff) |
Diffstat (limited to 'lib/Fuzzer')
-rw-r--r-- | lib/Fuzzer/FuzzerDriver.cpp | 1 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerFlags.def | 1 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerIO.h | 3 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerIOPosix.cpp | 6 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerIOWindows.cpp | 2 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerInternal.h | 1 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerLoop.cpp | 5 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerMerge.cpp | 12 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerOptions.h | 1 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerTraceState.cpp | 47 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerUtilPosix.cpp | 6 | ||||
-rw-r--r-- | lib/Fuzzer/FuzzerUtilWindows.cpp | 1 | ||||
-rw-r--r-- | lib/Fuzzer/test/merge.test | 8 |
13 files changed, 45 insertions, 49 deletions
diff --git a/lib/Fuzzer/FuzzerDriver.cpp b/lib/Fuzzer/FuzzerDriver.cpp index e6c9764f1133..2bbcb25275e4 100644 --- a/lib/Fuzzer/FuzzerDriver.cpp +++ b/lib/Fuzzer/FuzzerDriver.cpp @@ -468,6 +468,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.HandleXfsz = Flags.handle_xfsz; SetSignalHandler(Options); if (Flags.minimize_crash_internal_step) diff --git a/lib/Fuzzer/FuzzerFlags.def b/lib/Fuzzer/FuzzerFlags.def index 08eaad9856be..22aad353acec 100644 --- a/lib/Fuzzer/FuzzerFlags.def +++ b/lib/Fuzzer/FuzzerFlags.def @@ -91,6 +91,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_xfsz, 1, "If 1, try to intercept SIGXFSZ.") FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; " "if 2, close stderr; if 3, close both. " "Be careful, this will also close e.g. asan's stderr/stdout.") diff --git a/lib/Fuzzer/FuzzerIO.h b/lib/Fuzzer/FuzzerIO.h index 741fecf415b0..15bfd3d34727 100644 --- a/lib/Fuzzer/FuzzerIO.h +++ b/lib/Fuzzer/FuzzerIO.h @@ -37,6 +37,9 @@ std::string DirPlusFile(const std::string &DirPath, // Returns the name of the dir, similar to the 'dirname' utility. std::string DirName(const std::string &FileName); +// Returns path to a TmpDir. +std::string TmpDir(); + void DupAndCloseStderr(); void CloseStdout(); diff --git a/lib/Fuzzer/FuzzerIOPosix.cpp b/lib/Fuzzer/FuzzerIOPosix.cpp index 720bc1304594..6d8edf6ff538 100644 --- a/lib/Fuzzer/FuzzerIOPosix.cpp +++ b/lib/Fuzzer/FuzzerIOPosix.cpp @@ -83,6 +83,12 @@ std::string DirName(const std::string &FileName) { return Res; } +std::string TmpDir() { + if (auto Env = getenv("TMPDIR")) + return Env; + return "/tmp"; +} + } // namespace fuzzer #endif // LIBFUZZER_POSIX diff --git a/lib/Fuzzer/FuzzerIOWindows.cpp b/lib/Fuzzer/FuzzerIOWindows.cpp index a4738eb9dfe5..056f0721a336 100644 --- a/lib/Fuzzer/FuzzerIOWindows.cpp +++ b/lib/Fuzzer/FuzzerIOWindows.cpp @@ -277,6 +277,8 @@ std::string DirName(const std::string &FileName) { return FileName.substr(0, LocationLen + DirLen); } +std::string TmpDir() { return "TODO: implement TmpDir"; } + } // namespace fuzzer #endif // LIBFUZZER_WINDOWS diff --git a/lib/Fuzzer/FuzzerInternal.h b/lib/Fuzzer/FuzzerInternal.h index c041706092db..0d2c7a78aca8 100644 --- a/lib/Fuzzer/FuzzerInternal.h +++ b/lib/Fuzzer/FuzzerInternal.h @@ -82,6 +82,7 @@ public: static void StaticAlarmCallback(); static void StaticCrashSignalCallback(); static void StaticInterruptCallback(); + static void StaticFileSizeExceedCallback(); void ExecuteCallback(const uint8_t *Data, size_t Size); size_t RunOne(const uint8_t *Data, size_t Size); diff --git a/lib/Fuzzer/FuzzerLoop.cpp b/lib/Fuzzer/FuzzerLoop.cpp index 1336f5e4aeeb..9f49d1557990 100644 --- a/lib/Fuzzer/FuzzerLoop.cpp +++ b/lib/Fuzzer/FuzzerLoop.cpp @@ -266,6 +266,11 @@ void Fuzzer::StaticInterruptCallback() { F->InterruptCallback(); } +void Fuzzer::StaticFileSizeExceedCallback() { + Printf("==%lu== ERROR: libFuzzer: file size exceeded\n", GetPid()); + exit(1); +} + void Fuzzer::CrashCallback() { Printf("==%lu== ERROR: libFuzzer: deadly signal\n", GetPid()); if (EF->__sanitizer_print_stack_trace) diff --git a/lib/Fuzzer/FuzzerMerge.cpp b/lib/Fuzzer/FuzzerMerge.cpp index 84660e0fe53f..9e559115680c 100644 --- a/lib/Fuzzer/FuzzerMerge.cpp +++ b/lib/Fuzzer/FuzzerMerge.cpp @@ -220,8 +220,8 @@ void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args, ListFilesInDirRecursive(Corpora[i], nullptr, &AllFiles, /*TopDir*/true); Printf("MERGE-OUTER: %zd files, %zd in the initial corpus\n", AllFiles.size(), NumFilesInFirstCorpus); - std::string CFPath = - "libFuzzerTemp." + std::to_string(GetPid()) + ".txt"; + auto CFPath = DirPlusFile(TmpDir(), + "libFuzzerTemp." + std::to_string(GetPid()) + ".txt"); // Write the control file. RemoveFile(CFPath); std::ofstream ControlFile(CFPath); @@ -229,6 +229,11 @@ void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args, ControlFile << NumFilesInFirstCorpus << "\n"; for (auto &Path: AllFiles) ControlFile << Path << "\n"; + if (!ControlFile) { + Printf("MERGE-OUTER: failed to write to the control file: %s\n", + CFPath.c_str()); + exit(1); + } ControlFile.close(); // Execute the inner process untill it passes. @@ -246,6 +251,9 @@ void Fuzzer::CrashResistantMerge(const std::vector<std::string> &Args, // Read the control file and do the merge. Merger M; std::ifstream IF(CFPath); + IF.seekg(0, IF.end); + Printf("MERGE-OUTER: the control file has %zd bytes\n", (size_t)IF.tellg()); + IF.seekg(0, IF.beg); M.ParseOrExit(IF, true); IF.close(); std::vector<std::string> NewFiles; diff --git a/lib/Fuzzer/FuzzerOptions.h b/lib/Fuzzer/FuzzerOptions.h index cb702d285200..6f72205600b9 100644 --- a/lib/Fuzzer/FuzzerOptions.h +++ b/lib/Fuzzer/FuzzerOptions.h @@ -62,6 +62,7 @@ struct FuzzingOptions { bool HandleInt = false; bool HandleSegv = false; bool HandleTerm = false; + bool HandleXfsz = false; }; } // namespace fuzzer diff --git a/lib/Fuzzer/FuzzerTraceState.cpp b/lib/Fuzzer/FuzzerTraceState.cpp index be62a6624b27..2ad9702fab0e 100644 --- a/lib/Fuzzer/FuzzerTraceState.cpp +++ b/lib/Fuzzer/FuzzerTraceState.cpp @@ -46,10 +46,6 @@ public: void TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1, const uint8_t *Data2); - void TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits, uint64_t Val, - size_t NumCases, uint64_t *Cases); - int TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData, - size_t DataSize); int TryToAddDesiredData(const uint8_t *PresentData, const uint8_t *DesiredData, size_t DataSize); @@ -147,29 +143,6 @@ public: size_t AutoDictAdds = 0; }; -int TraceState::TryToAddDesiredData(uint64_t PresentData, uint64_t DesiredData, - size_t DataSize) { - if (NumMutations >= kMaxMutations || !WantToHandleOneMoreMutation()) return 0; - ScopedDoingMyOwnMemmem scoped_doing_my_own_memmem; - const uint8_t *UnitData; - auto UnitSize = F->GetCurrentUnitInFuzzingThead(&UnitData); - int Res = 0; - const uint8_t *Beg = UnitData; - const uint8_t *End = Beg + UnitSize; - for (const uint8_t *Cur = Beg; Cur < End; Cur++) { - Cur = (uint8_t *)SearchMemory(Cur, End - Cur, &PresentData, DataSize); - if (!Cur) - break; - size_t Pos = Cur - Beg; - assert(Pos < UnitSize); - AddMutation(Pos, DataSize, DesiredData); - AddMutation(Pos, DataSize, DesiredData + 1); - AddMutation(Pos, DataSize, DesiredData - 1); - Res++; - } - return Res; -} - int TraceState::TryToAddDesiredData(const uint8_t *PresentData, const uint8_t *DesiredData, size_t DataSize) { @@ -206,26 +179,6 @@ void TraceState::TraceMemcmpCallback(size_t CmpSize, const uint8_t *Data1, } } -void TraceState::TraceSwitchCallback(uintptr_t PC, size_t ValSizeInBits, - uint64_t Val, size_t NumCases, - uint64_t *Cases) { - if (F->InFuzzingThread()) return; - size_t ValSize = ValSizeInBits / 8; - bool TryShort = IsTwoByteData(Val); - for (size_t i = 0; i < NumCases; i++) - TryShort &= IsTwoByteData(Cases[i]); - - if (Options.Verbosity >= 3) - Printf("TraceSwitch: %p %zd # %zd; TryShort %d\n", PC, Val, NumCases, - TryShort); - - for (size_t i = 0; i < NumCases; i++) { - TryToAddDesiredData(Val, Cases[i], ValSize); - if (TryShort) - TryToAddDesiredData(Val, Cases[i], 2); - } -} - static TraceState *TS; void Fuzzer::StartTraceRecording() { diff --git a/lib/Fuzzer/FuzzerUtilPosix.cpp b/lib/Fuzzer/FuzzerUtilPosix.cpp index 8b484b8effa4..e8d48dc81a3b 100644 --- a/lib/Fuzzer/FuzzerUtilPosix.cpp +++ b/lib/Fuzzer/FuzzerUtilPosix.cpp @@ -41,6 +41,10 @@ static void InterruptHandler(int, siginfo_t *, void *) { Fuzzer::StaticInterruptCallback(); } +static void FileSizeExceedHandler(int, siginfo_t *, void *) { + Fuzzer::StaticFileSizeExceedCallback(); +} + static void SetSigaction(int signum, void (*callback)(int, siginfo_t *, void *)) { struct sigaction sigact; @@ -80,6 +84,8 @@ void SetSignalHandler(const FuzzingOptions& Options) { SetSigaction(SIGILL, CrashHandler); if (Options.HandleFpe) SetSigaction(SIGFPE, CrashHandler); + if (Options.HandleXfsz) + SetSigaction(SIGXFSZ, FileSizeExceedHandler); } void SleepSeconds(int Seconds) { diff --git a/lib/Fuzzer/FuzzerUtilWindows.cpp b/lib/Fuzzer/FuzzerUtilWindows.cpp index 64adb7cd1380..3ca1f2c8f562 100644 --- a/lib/Fuzzer/FuzzerUtilWindows.cpp +++ b/lib/Fuzzer/FuzzerUtilWindows.cpp @@ -58,6 +58,7 @@ LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) { if (HandlerOpt->HandleFpe) Fuzzer::StaticCrashSignalCallback(); break; + // TODO: handle (Options.HandleXfsz) } return EXCEPTION_CONTINUE_SEARCH; } diff --git a/lib/Fuzzer/test/merge.test b/lib/Fuzzer/test/merge.test index 1f1810eb0195..5c7d30e41caa 100644 --- a/lib/Fuzzer/test/merge.test +++ b/lib/Fuzzer/test/merge.test @@ -44,3 +44,11 @@ MERGE_WITH_CRASH: MERGE-OUTER: 3 new files # Check that we actually limit the size with max_len RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5 MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s) + +# Check that we honor TMPDIR +RUN: TMPDIR=DIR_DOES_NOT_EXIST not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR +TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp + +# Check that we can report an error if file size exceeded +RUN: (ulimit -f 1; not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ) +SIGXFSZ: ERROR: libFuzzer: file size exceeded |