[PATCH] D27433: [libFuzzer] Diff 16 - Fix bug in detecting timeouts when input string is empty.

Marcos Pividori via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 5 16:25:44 PST 2016


mpividori created this revision.
mpividori added reviewers: kcc, zturner.
mpividori added a subscriber: llvm-commits.
mpividori set the repository for this revision to rL LLVM.
Herald added a subscriber: mgorny.

I added a new flag `RunningCB` to know if the Fuzzer's main thread is running the CB function, instead of using `(! CurrentUnitSize)`. `(! CurrentUnitSize)` doesn't work properly. For example, in `FuzzerLoop.cpp`, inside `ShuffleAndMinimize()` function, we execute the callback with an empty string (size=0). Previous implementation failed to detect timeouts in that execution.
Also, I add a regression test for that case.


Repository:
  rL LLVM

https://reviews.llvm.org/D27433

Files:
  lib/Fuzzer/FuzzerInternal.h
  lib/Fuzzer/FuzzerLoop.cpp
  lib/Fuzzer/test/CMakeLists.txt
  lib/Fuzzer/test/TimeoutEmptyTest.cpp
  lib/Fuzzer/test/fuzzer-timeout.test


Index: lib/Fuzzer/test/fuzzer-timeout.test
===================================================================
--- lib/Fuzzer/test/fuzzer-timeout.test
+++ lib/Fuzzer/test/fuzzer-timeout.test
@@ -12,3 +12,8 @@
 SingleInputTimeoutTest-NOT: Test unit written to ./timeout-
 
 RUN: LLVMFuzzer-TimeoutTest -timeout=1 -timeout_exitcode=0
+
+RUN: not LLVMFuzzer-TimeoutEmptyTest -timeout=1 2>&1 | FileCheck %s --check-prefix=TimeoutEmptyTest
+TimeoutEmptyTest: ALARM: working on the last Unit for
+TimeoutEmptyTest: == ERROR: libFuzzer: timeout after
+TimeoutEmptyTest: SUMMARY: libFuzzer: timeout
Index: lib/Fuzzer/test/TimeoutEmptyTest.cpp
===================================================================
--- /dev/null
+++ lib/Fuzzer/test/TimeoutEmptyTest.cpp
@@ -0,0 +1,12 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find the empty string.
+#include <cstdint>
+#include <cstddef>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  while (!Size)
+    ;
+  return 0;
+}
Index: lib/Fuzzer/test/CMakeLists.txt
===================================================================
--- lib/Fuzzer/test/CMakeLists.txt
+++ lib/Fuzzer/test/CMakeLists.txt
@@ -109,6 +109,7 @@
   ThreadedLeakTest
   ThreadedTest
   TimeoutTest
+  TimeoutEmptyTest
   TraceMallocTest
   )
 
Index: lib/Fuzzer/FuzzerLoop.cpp
===================================================================
--- lib/Fuzzer/FuzzerLoop.cpp
+++ lib/Fuzzer/FuzzerLoop.cpp
@@ -284,7 +284,7 @@
 void Fuzzer::AlarmCallback() {
   assert(Options.UnitTimeoutSec > 0);
   if (!InFuzzingThread()) return;
-  if (!CurrentUnitSize)
+  if (!RunningCB)
     return; // We have not started running units yet.
   size_t Seconds =
       duration_cast<seconds>(system_clock::now() - UnitStartTime).count();
@@ -528,7 +528,9 @@
   UnitStartTime = system_clock::now();
   ResetCounters();  // Reset coverage right before the callback.
   TPC.ResetMaps();
+  RunningCB = true;
   int Res = CB(DataCopy, Size);
+  RunningCB = false;
   UnitStopTime = system_clock::now();
   (void)Res;
   assert(Res == 0);
Index: lib/Fuzzer/FuzzerInternal.h
===================================================================
--- lib/Fuzzer/FuzzerInternal.h
+++ lib/Fuzzer/FuzzerInternal.h
@@ -144,6 +144,7 @@
   uint8_t *CurrentUnitData = nullptr;
   std::atomic<size_t> CurrentUnitSize;
   uint8_t BaseSha1[kSHA1NumBytes];  // Checksum of the base unit.
+  bool RunningCB = false;
 
   size_t TotalNumberOfRuns = 0;
   size_t NumberOfNewUnitsAdded = 0;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27433.80343.patch
Type: text/x-patch
Size: 2622 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161206/e769c0a5/attachment.bin>


More information about the llvm-commits mailing list