[compiler-rt] r336619 - [libFuzzer] Make -fsanitize=memory, fuzzer work.

Matt Morehouse via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 9 16:51:08 PDT 2018


Author: morehouse
Date: Mon Jul  9 16:51:08 2018
New Revision: 336619

URL: http://llvm.org/viewvc/llvm-project?rev=336619&view=rev
Log:
[libFuzzer] Make -fsanitize=memory,fuzzer work.

This patch allows libFuzzer to fuzz applications instrumented with MSan
without recompiling libFuzzer with MSan instrumentation.

Fixes https://github.com/google/sanitizers/issues/958.

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

Added:
    compiler-rt/trunk/test/fuzzer/UninitializedStrlen.cpp
    compiler-rt/trunk/test/fuzzer/UseAfterDtor.cpp
    compiler-rt/trunk/test/fuzzer/msan.test
Modified:
    compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
    compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def
    compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h
    compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
    compiler-rt/trunk/test/fuzzer/lit.cfg

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp?rev=336619&r1=336618&r2=336619&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerDriver.cpp Mon Jul  9 16:51:08 2018
@@ -537,6 +537,8 @@ int FuzzerDriver(int *argc, char ***argv
   EF = new ExternalFunctions();
   if (EF->LLVMFuzzerInitialize)
     EF->LLVMFuzzerInitialize(argc, argv);
+  if (EF->__msan_scoped_disable_interceptor_checks)
+    EF->__msan_scoped_disable_interceptor_checks();
   const Vector<std::string> Args(*argv, *argv + *argc);
   assert(!Args.empty());
   ProgName = new std::string(Args[0]);

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def?rev=336619&r1=336618&r2=336619&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerExtFunctions.def Mon Jul  9 16:51:08 2018
@@ -46,3 +46,6 @@ EXT_FUNC(__sanitizer_set_death_callback,
 EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);
 EXT_FUNC(__sanitizer_dump_coverage, void, (const uintptr_t *, uintptr_t),
          false);
+EXT_FUNC(__msan_scoped_disable_interceptor_checks, void, (), false);
+EXT_FUNC(__msan_scoped_enable_interceptor_checks, void, (), false);
+EXT_FUNC(__msan_unpoison, void, (const volatile void *, size_t size), false);

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h?rev=336619&r1=336618&r2=336619&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerInternal.h Mon Jul  9 16:51:08 2018
@@ -152,6 +152,28 @@ private:
   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

Modified: compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp?rev=336619&r1=336618&r2=336619&view=diff
==============================================================================
--- compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp (original)
+++ compiler-rt/trunk/lib/fuzzer/FuzzerLoop.cpp Mon Jul  9 16:51:08 2018
@@ -179,6 +179,7 @@ void Fuzzer::StaticDeathCallback() {
 void Fuzzer::DumpCurrentUnit(const char *Prefix) {
   if (!CurrentUnitData)
     return; // Happens when running individual inputs.
+  ScopedDisableMsanInterceptorChecks S;
   MD.PrintMutationSequence();
   Printf("; base unit: %s\n", Sha1ToString(BaseSha1).c_str());
   size_t UnitSize = CurrentUnitSize;
@@ -516,19 +517,24 @@ void Fuzzer::ExecuteCallback(const uint8
   // so that we reliably find buffer overflows in it.
   uint8_t *DataCopy = new uint8_t[Size];
   memcpy(DataCopy, Data, Size);
+  if (EF->__msan_unpoison)
+    EF->__msan_unpoison(DataCopy, Size);
   if (CurrentUnitData && CurrentUnitData != Data)
     memcpy(CurrentUnitData, Data, Size);
   CurrentUnitSize = Size;
-  AllocTracer.Start(Options.TraceMalloc);
-  UnitStartTime = system_clock::now();
-  TPC.ResetMaps();
-  RunningCB = true;
-  int Res = CB(DataCopy, Size);
-  RunningCB = false;
-  UnitStopTime = system_clock::now();
-  (void)Res;
-  assert(Res == 0);
-  HasMoreMallocsThanFrees = AllocTracer.Stop();
+  {
+    ScopedEnableMsanInterceptorChecks S;
+    AllocTracer.Start(Options.TraceMalloc);
+    UnitStartTime = system_clock::now();
+    TPC.ResetMaps();
+    RunningCB = true;
+    int Res = CB(DataCopy, Size);
+    RunningCB = false;
+    UnitStopTime = system_clock::now();
+    (void)Res;
+    assert(Res == 0);
+    HasMoreMallocsThanFrees = AllocTracer.Stop();
+  }
   if (!LooseMemeq(DataCopy, Data, Size))
     CrashOnOverwrittenData();
   CurrentUnitSize = 0;

Added: compiler-rt/trunk/test/fuzzer/UninitializedStrlen.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/UninitializedStrlen.cpp?rev=336619&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/UninitializedStrlen.cpp (added)
+++ compiler-rt/trunk/test/fuzzer/UninitializedStrlen.cpp Mon Jul  9 16:51:08 2018
@@ -0,0 +1,14 @@
+#include <cstdint>
+#include <cstring>
+
+volatile size_t Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  if (Size < 4) return 0;
+  if (Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' && Data[3] == 'Z') {
+    char uninit[7];
+    Sink = strlen(uninit);
+  }
+  return 0;
+}
+

Added: compiler-rt/trunk/test/fuzzer/UseAfterDtor.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/UseAfterDtor.cpp?rev=336619&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/UseAfterDtor.cpp (added)
+++ compiler-rt/trunk/test/fuzzer/UseAfterDtor.cpp Mon Jul  9 16:51:08 2018
@@ -0,0 +1,27 @@
+#include <cstdint>
+#include <cstdio>
+
+struct Simple {
+  int x_;
+  Simple() {
+    x_ = 5;
+  }
+  ~Simple() {
+    x_ += 1;
+  }
+};
+
+Simple *volatile SimpleSink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+  if (Size < 4) return 0;
+  if (Data[0] == 'F' && Data[1] == 'U' && Data[2] == 'Z' && Data[3] == 'Z') {
+    {
+      Simple S;
+      SimpleSink = &S;
+    }
+    if (SimpleSink->x_) fprintf(stderr, "Failed to catch use-after-dtor\n");
+  }
+  return 0;
+}
+

Modified: compiler-rt/trunk/test/fuzzer/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/lit.cfg?rev=336619&r1=336618&r2=336619&view=diff
==============================================================================
--- compiler-rt/trunk/test/fuzzer/lit.cfg (original)
+++ compiler-rt/trunk/test/fuzzer/lit.cfg Mon Jul  9 16:51:08 2018
@@ -49,7 +49,7 @@ config.substitutions.append(('%build_dir
 libfuzzer_src_root = os.path.join(config.compiler_rt_src_root, "lib", "fuzzer")
 config.substitutions.append(('%libfuzzer_src', libfuzzer_src_root))
 
-def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True):
+def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False):
   compiler_cmd = config.clang
   extra_cmd = config.target_flags
   if config.clang and config.stdlib == 'libc++':
@@ -63,7 +63,10 @@ def generate_compiler_cmd(is_cpp=True, f
     link_cmd = '-lstdc++'
 
   std_cmd = '--driver-mode=g++ -std=c++11' if is_cpp else ''
-  sanitizers = ['address']
+  if msan_enabled:
+    sanitizers = ['memory']
+  else:
+    sanitizers = ['address']
   if fuzzer_enabled:
     sanitizers.append('fuzzer')
   sanitizers_cmd = ('-fsanitize=%s' % ','.join(sanitizers))
@@ -93,6 +96,10 @@ config.substitutions.append(('%no_fuzzer
       generate_compiler_cmd(is_cpp=False, fuzzer_enabled=False)
       ))
 
+config.substitutions.append(('%msan_compiler',
+      generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=True)
+      ))
+
 if config.host_os == 'Darwin':
   if config.target_arch in ["x86_64", "x86_64h"]:
     config.parallelism_group = "darwin-64bit-sanitizer"

Added: compiler-rt/trunk/test/fuzzer/msan.test
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/fuzzer/msan.test?rev=336619&view=auto
==============================================================================
--- compiler-rt/trunk/test/fuzzer/msan.test (added)
+++ compiler-rt/trunk/test/fuzzer/msan.test Mon Jul  9 16:51:08 2018
@@ -0,0 +1,23 @@
+RUN: %msan_compiler %S/SimpleTest.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+RUN: %msan_compiler %S/SimpleCmpTest.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+RUN: %msan_compiler %S/MemcmpTest.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+RUN: %msan_compiler %S/StrcmpTest.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT
+
+NO-REPORT-NOT: MemorySanitizer
+NO-REPORT: BINGO
+
+
+RUN: %msan_compiler %S/UseAfterDtor.cpp -o %t
+RUN: MSAN_OPTIONS=poison_in_dtor=1 not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=REPORT
+
+RUN: %msan_compiler %S/UninitializedStrlen.cpp -o %t
+RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=REPORT
+
+REPORT: MemorySanitizer: use-of-uninitialized-value




More information about the llvm-commits mailing list