[libFuzzer] add a flag close_fd_mask so that we can silence spammy targets by closing...
authorKostya Serebryany <kcc@google.com>
Fri, 18 Mar 2016 20:58:29 +0000 (20:58 +0000)
committerKostya Serebryany <kcc@google.com>
Fri, 18 Mar 2016 20:58:29 +0000 (20:58 +0000)
llvm-svn: 263831

llvm/docs/LibFuzzer.rst
llvm/lib/Fuzzer/FuzzerDriver.cpp
llvm/lib/Fuzzer/FuzzerFlags.def
llvm/lib/Fuzzer/FuzzerIO.cpp
llvm/lib/Fuzzer/FuzzerInternal.h
llvm/lib/Fuzzer/test/CMakeLists.txt
llvm/lib/Fuzzer/test/SpamyTest.cpp [new file with mode: 0644]
llvm/lib/Fuzzer/test/fuzzer.test

index 3d35631..bb42b61 100644 (file)
@@ -88,6 +88,7 @@ The most important flags are::
   artifact_prefix                       ""      Write fuzzing artifacts (crash, timeout, or slow inputs) as $(artifact_prefix)file
   exact_artifact_path                   ""      Write the single artifact on failure (crash, timeout) as $(exact_artifact_path). This overrides -artifact_prefix and will not use checksum in the file name. Do not use the same path for several parallel processes.
   print_final_stats                     0       If 1, print statistics at exit.
+  close_fd_mask                         0       If 1, close stdout at startup; if 2, close stderr; if 3, close both.
 
 For the full list of flags run the fuzzer binary with ``-help=1``.
 
index c162adf..a31d306 100644 (file)
@@ -260,6 +260,11 @@ static int FuzzerDriver(const std::vector<std::string> &Args,
     return 0;
   }
 
+  if (Flags.close_fd_mask & 2)
+    DupAndCloseStderr();
+  if (Flags.close_fd_mask & 1)
+    CloseStdout();
+
   if (Flags.jobs > 0 && Flags.workers == 0) {
     Flags.workers = std::min(NumberOfCpuCores() / 2, Flags.jobs);
     if (Flags.workers > 1)
index 33389d2..20ffa32 100644 (file)
@@ -75,6 +75,8 @@ FUZZER_FLAG_INT(handle_abrt, 1, "If 1, try to intercept SIGABRT.")
 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(close_fd_mask, 0, "If 1, close stdout at startup; "
+                                       "if 2, close stderr; if 3, close both.")
 
 FUZZER_DEPRECATED_FLAG(exit_on_first)
 FUZZER_DEPRECATED_FLAG(save_minimized_corpus)
index 1e14cfc..358e645 100644 (file)
@@ -20,6 +20,8 @@
 
 namespace fuzzer {
 
+static int OutputFd = 2;
+
 bool IsFile(const std::string &Path) {
   struct stat St;
   if (stat(Path.c_str(), &St))
@@ -114,11 +116,25 @@ std::string DirPlusFile(const std::string &DirPath,
   return DirPath + "/" + FileName;
 }
 
+void DupAndCloseStderr() {
+  assert(OutputFd == 2);
+  OutputFd = dup(OutputFd);
+  if (OutputFd < 0)
+    OutputFd = 2;
+  else
+    close(2);
+}
+
+void CloseStdout() { close(1); }
+
 void Printf(const char *Fmt, ...) {
+  char Buf[1024];
   va_list ap;
   va_start(ap, Fmt);
-  vfprintf(stderr, Fmt, ap);
+  int Formatted = vsnprintf(Buf, sizeof(Buf), Fmt, ap);
   va_end(ap);
+  if (Formatted)
+    write(OutputFd, Buf, Formatted);
 }
 
 }  // namespace fuzzer
index ebed95c..2ff1319 100644 (file)
@@ -75,6 +75,8 @@ void CopyFileToErr(const std::string &Path);
 std::string DirPlusFile(const std::string &DirPath,
                         const std::string &FileName);
 
+void DupAndCloseStderr();
+void CloseStdout();
 void Printf(const char *Fmt, ...);
 void PrintHexArray(const Unit &U, const char *PrintAfter = "");
 void PrintHexArray(const uint8_t *Data, size_t Size,
index 83dbbbc..255be9c 100644 (file)
@@ -30,6 +30,7 @@ set(Tests
   SimpleFnAdapterTest
   SimpleHashTest
   SimpleTest
+  SpamyTest
   StrcmpTest
   StrncmpTest
   SwitchTest
diff --git a/llvm/lib/Fuzzer/test/SpamyTest.cpp b/llvm/lib/Fuzzer/test/SpamyTest.cpp
new file mode 100644 (file)
index 0000000..63776d6
--- /dev/null
@@ -0,0 +1,18 @@
+// The test spams to stderr and stdout.
+#include <assert.h>
+#include <cstdint>
+#include <cstdio>
+#include <cstddef>
+#include <iostream>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  assert(Data);
+  printf("PRINTF_STDOUT\n");
+  fflush(stdout);
+  fprintf(stderr, "PRINTF_STDERR\n");
+  std::cout << "STREAM_COUT\n";
+  std::cout.flush();
+  std::cerr << "STREAM_CERR\n";
+  return 0;
+}
+
index 3ab7673..240209d 100644 (file)
@@ -91,3 +91,32 @@ FINAL_STATS: stat::new_units_added:
 FINAL_STATS: stat::slowest_unit_time_sec:    0
 FINAL_STATS: stat::peak_rss_mb:
 
+RUN: LLVMFuzzer-SpamyTest -runs=1                  2>&1 | FileCheck %s --check-prefix=FD_MASK_0
+RUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=0 2>&1 | FileCheck %s --check-prefix=FD_MASK_0
+RUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=1 2>&1 | FileCheck %s --check-prefix=FD_MASK_1
+RUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=2 2>&1 | FileCheck %s --check-prefix=FD_MASK_2
+RUN: LLVMFuzzer-SpamyTest -runs=1 -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=FD_MASK_3
+FD_MASK_0: PRINTF_STDOUT
+FD_MASK_0: PRINTF_STDERR
+FD_MASK_0: STREAM_COUT
+FD_MASK_0: STREAM_CERR
+FD_MASK_0: INITED
+
+FD_MASK_1-NOT: PRINTF_STDOUT
+FD_MASK_1: PRINTF_STDERR
+FD_MASK_1-NOT: STREAM_COUT
+FD_MASK_1: STREAM_CERR
+FD_MASK_1: INITED
+
+FD_MASK_2: PRINTF_STDOUT
+FD_MASK_2-NOT: PRINTF_STDERR
+FD_MASK_2: STREAM_COUT
+FD_MASK_2-NOTE: STREAM_CERR
+FD_MASK_2: INITED
+
+FD_MASK_3-NOT: PRINTF_STDOUT
+FD_MASK_3-NOT: PRINTF_STDERR
+FD_MASK_3-NOT: STREAM_COUT
+FD_MASK_3-NOT: STREAM_CERR
+FD_MASK_3: INITED
+