Revert "[libFuzzer] Link libFuzzer's own interceptors when other compiler runtimes...
authorRichard Smith <richard@metafoo.co.uk>
Fri, 17 Jul 2020 01:06:06 +0000 (18:06 -0700)
committerRichard Smith <richard@metafoo.co.uk>
Fri, 17 Jul 2020 01:06:37 +0000 (18:06 -0700)
This causes binaries linked with this runtime to crash on startup if
dlsym uses any of the intercepted functions. (For example, that happens
when using tcmalloc as the allocator: dlsym attempts to allocate memory
with malloc, and tcmalloc uses strncmp within its implementation.)

Also revert dependent commit "[libFuzzer] Disable implicit builtin knowledge about memcmp-like functions when -fsanitize=fuzzer-no-link is given."

This reverts commit f78d9fceea736d431e9e3cbca291e3909e3aa46d and 12d1124c49beec0fb79d36944960e5bf0f236d4c.

clang/include/clang/Driver/SanitizerArgs.h
clang/lib/Driver/SanitizerArgs.cpp
clang/lib/Driver/ToolChains/CommonArgs.cpp
compiler-rt/lib/fuzzer/CMakeLists.txt
compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp [deleted file]
compiler-rt/test/fuzzer/memcmp.test
compiler-rt/test/fuzzer/memcmp64.test
compiler-rt/test/fuzzer/strcmp.test
compiler-rt/test/fuzzer/strncmp.test
compiler-rt/test/fuzzer/strstr.test

index 563d6c3..934dab8 100644 (file)
@@ -74,7 +74,6 @@ class SanitizerArgs {
            !Sanitizers.has(SanitizerKind::Address) &&
            !Sanitizers.has(SanitizerKind::HWAddress);
   }
-  bool needsFuzzerInterceptors() const;
   bool needsUbsanRt() const;
   bool requiresMinimalRuntime() const { return MinimalRuntime; }
   bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
index 4af2466..bcc9ffc 100644 (file)
@@ -240,10 +240,6 @@ static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
   return TrappingKinds;
 }
 
-bool SanitizerArgs::needsFuzzerInterceptors() const {
-  return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt();
-}
-
 bool SanitizerArgs::needsUbsanRt() const {
   // All of these include ubsan.
   if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
@@ -1088,22 +1084,6 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
       Sanitizers.has(SanitizerKind::Address))
     CmdArgs.push_back("-fno-assume-sane-operator-new");
 
-  // libFuzzer wants to intercept calls to certain library functions, so the
-  // following -fno-builtin-* flags force the compiler to emit interposable
-  // libcalls to these functions. Other sanitizers effectively do the same thing
-  // by marking all library call sites with NoBuiltin attribute in their LLVM
-  // pass. (see llvm::maybeMarkSanitizerLibraryCallNoBuiltin)
-  if (Sanitizers.has(SanitizerKind::FuzzerNoLink)) {
-    CmdArgs.push_back("-fno-builtin-memcmp");
-    CmdArgs.push_back("-fno-builtin-strncmp");
-    CmdArgs.push_back("-fno-builtin-strcmp");
-    CmdArgs.push_back("-fno-builtin-strncasecmp");
-    CmdArgs.push_back("-fno-builtin-strcasecmp");
-    CmdArgs.push_back("-fno-builtin-strstr");
-    CmdArgs.push_back("-fno-builtin-strcasestr");
-    CmdArgs.push_back("-fno-builtin-memmem");
-  }
-
   // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
   // enabled.
   if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
index acde6d9..6b6e276 100644 (file)
@@ -784,9 +784,6 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
       !Args.hasArg(options::OPT_shared)) {
 
     addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true);
-    if (SanArgs.needsFuzzerInterceptors())
-      addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer_interceptors", false,
-                          true);
     if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx))
       TC.AddCXXStdlibLibArgs(Args, CmdArgs);
   }
index 02be89c..b5be6b8 100644 (file)
@@ -99,13 +99,6 @@ add_compiler_rt_object_libraries(RTfuzzer_main
   CFLAGS ${LIBFUZZER_CFLAGS}
   DEPS ${LIBFUZZER_DEPS})
 
-add_compiler_rt_object_libraries(RTfuzzer_interceptors
-  OS ${FUZZER_SUPPORTED_OS}
-  ARCHS ${FUZZER_SUPPORTED_ARCH}
-  SOURCES FuzzerInterceptors.cpp
-  CFLAGS ${LIBFUZZER_CFLAGS}
-  DEPS ${LIBFUZZER_DEPS})
-
 add_compiler_rt_runtime(clang_rt.fuzzer
   STATIC
   OS ${FUZZER_SUPPORTED_OS}
@@ -122,14 +115,6 @@ add_compiler_rt_runtime(clang_rt.fuzzer_no_main
   CFLAGS ${LIBFUZZER_CFLAGS}
   PARENT_TARGET fuzzer)
 
-add_compiler_rt_runtime(clang_rt.fuzzer_interceptors
-  STATIC
-  OS ${FUZZER_SUPPORTED_OS}
-  ARCHS ${FUZZER_SUPPORTED_ARCH}
-  OBJECT_LIBS RTfuzzer_interceptors
-  CFLAGS ${LIBFUZZER_CFLAGS}
-  PARENT_TARGET fuzzer)
-
 if(OS_NAME MATCHES "Linux|Fuchsia" AND
    COMPILER_RT_LIBCXX_PATH AND
    COMPILER_RT_LIBCXXABI_PATH)
@@ -163,10 +148,7 @@ if(OS_NAME MATCHES "Linux|Fuchsia" AND
     add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build)
     target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
     add_dependencies(RTfuzzer_main.${arch} libcxx_fuzzer_${arch}-build)
-    target_compile_options(RTfuzzer_interceptors.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
-    add_dependencies(RTfuzzer_interceptors.${arch} libcxx_fuzzer_${arch}-build)
     partially_link_libcxx(fuzzer_no_main ${LIBCXX_${arch}_PREFIX} ${arch})
-    partially_link_libcxx(fuzzer_interceptors ${LIBCXX_${arch}_PREFIX} ${arch})
     partially_link_libcxx(fuzzer ${LIBCXX_${arch}_PREFIX} ${arch})
   endforeach()
 endif()
diff --git a/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp b/compiler-rt/lib/fuzzer/FuzzerInterceptors.cpp
deleted file mode 100644 (file)
index cb55b4a..0000000
+++ /dev/null
@@ -1,170 +0,0 @@
-//===-- FuzzerInterceptors.cpp --------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-// Intercept certain libc functions to aid fuzzing.
-// Linked only when other RTs that define their own interceptors are not linked.
-//===----------------------------------------------------------------------===//
-
-#include "FuzzerPlatform.h"
-
-#if LIBFUZZER_LINUX
-
-#define GET_CALLER_PC() __builtin_return_address(0)
-
-#define PTR_TO_REAL(x) real_##x
-#define REAL(x) __interception::PTR_TO_REAL(x)
-#define FUNC_TYPE(x) x##_type
-#define DEFINE_REAL(ret_type, func, ...)                                       \
-  typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__);                            \
-  namespace __interception {                                                   \
-  FUNC_TYPE(func) PTR_TO_REAL(func);                                           \
-  }
-
-#include <cassert>
-#include <cstdint>
-#include <dlfcn.h> // for dlsym()
-#include <sanitizer/common_interface_defs.h>
-
-static void *getFuncAddr(const char *name, uintptr_t wrapper_addr) {
-  void *addr = dlsym(RTLD_NEXT, name);
-  if (!addr) {
-    // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
-    // later in the library search order than the DSO that we are trying to
-    // intercept, which means that we cannot intercept this function. We still
-    // want the address of the real definition, though, so look it up using
-    // RTLD_DEFAULT.
-    addr = dlsym(RTLD_DEFAULT, name);
-
-    // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
-    // We don't want to intercept the wrapper and have it point to itself.
-    if (reinterpret_cast<uintptr_t>(addr) == wrapper_addr)
-      addr = nullptr;
-  }
-  return addr;
-}
-
-static int FuzzerInited = 0;
-static bool FuzzerInitIsRunning;
-
-static void fuzzerInit();
-
-static void ensureFuzzerInited() {
-  assert(!FuzzerInitIsRunning);
-  if (!FuzzerInited) {
-    fuzzerInit();
-  }
-}
-
-extern "C" {
-
-DEFINE_REAL(int, memcmp, const void *, const void *, size_t)
-DEFINE_REAL(int, strncmp, const char *, const char *, size_t)
-DEFINE_REAL(int, strcmp, const char *, const char *)
-DEFINE_REAL(int, strncasecmp, const char *, const char *, size_t)
-DEFINE_REAL(int, strcasecmp, const char *, const char *)
-DEFINE_REAL(char *, strstr, const char *, const char *)
-DEFINE_REAL(char *, strcasestr, const char *, const char *)
-DEFINE_REAL(void *, memmem, const void *, size_t, const void *, size_t)
-
-ATTRIBUTE_INTERFACE int memcmp(const void *s1, const void *s2, size_t n) {
-  ensureFuzzerInited();
-  int result = REAL(memcmp)(s1, s2, n);
-  __sanitizer_weak_hook_memcmp(GET_CALLER_PC(), s1, s2, n, result);
-
-  return result;
-}
-
-ATTRIBUTE_INTERFACE int strncmp(const char *s1, const char *s2, size_t n) {
-  ensureFuzzerInited();
-  int result = REAL(strncmp)(s1, s2, n);
-  __sanitizer_weak_hook_strncmp(GET_CALLER_PC(), s1, s2, n, result);
-
-  return result;
-}
-
-ATTRIBUTE_INTERFACE int strcmp(const char *s1, const char *s2) {
-  ensureFuzzerInited();
-  int result = REAL(strcmp)(s1, s2);
-  __sanitizer_weak_hook_strcmp(GET_CALLER_PC(), s1, s2, result);
-
-  return result;
-}
-
-ATTRIBUTE_INTERFACE int strncasecmp(const char *s1, const char *s2, size_t n) {
-  ensureFuzzerInited();
-  int result = REAL(strncasecmp)(s1, s2, n);
-  __sanitizer_weak_hook_strncasecmp(GET_CALLER_PC(), s1, s2, n, result);
-
-  return result;
-}
-
-ATTRIBUTE_INTERFACE int strcasecmp(const char *s1, const char *s2) {
-  ensureFuzzerInited();
-  int result = REAL(strcasecmp)(s1, s2);
-  __sanitizer_weak_hook_strcasecmp(GET_CALLER_PC(), s1, s2, result);
-
-  return result;
-}
-
-ATTRIBUTE_INTERFACE char *strstr(const char *s1, const char *s2) {
-  ensureFuzzerInited();
-  char *result = REAL(strstr)(s1, s2);
-  __sanitizer_weak_hook_strstr(GET_CALLER_PC(), s1, s2, result);
-
-  return result;
-}
-
-ATTRIBUTE_INTERFACE char *strcasestr(const char *s1, const char *s2) {
-  ensureFuzzerInited();
-  char *result = REAL(strcasestr)(s1, s2);
-  __sanitizer_weak_hook_strcasestr(GET_CALLER_PC(), s1, s2, result);
-
-  return result;
-}
-
-ATTRIBUTE_INTERFACE
-void *memmem(const void *s1, size_t len1, const void *s2, size_t len2) {
-  ensureFuzzerInited();
-  void *result = REAL(memmem)(s1, len1, s2, len2);
-  __sanitizer_weak_hook_memmem(GET_CALLER_PC(), s1, len1, s2, len2, result);
-
-  return result;
-}
-
-__attribute__((section(".preinit_array"),
-               used)) static void (*__local_fuzzer_preinit)(void) = fuzzerInit;
-
-} // extern "C"
-
-static void fuzzerInit() {
-  assert(!FuzzerInitIsRunning);
-  if (FuzzerInited)
-    return;
-  FuzzerInitIsRunning = true;
-
-  REAL(memcmp) = reinterpret_cast<memcmp_type>(
-      getFuncAddr("memcmp", reinterpret_cast<uintptr_t>(&memcmp)));
-  REAL(strncmp) = reinterpret_cast<strncmp_type>(
-      getFuncAddr("strncmp", reinterpret_cast<uintptr_t>(&strncmp)));
-  REAL(strcmp) = reinterpret_cast<strcmp_type>(
-      getFuncAddr("strcmp", reinterpret_cast<uintptr_t>(&strcmp)));
-  REAL(strncasecmp) = reinterpret_cast<strncasecmp_type>(
-      getFuncAddr("strncasecmp", reinterpret_cast<uintptr_t>(&strncasecmp)));
-  REAL(strcasecmp) = reinterpret_cast<strcasecmp_type>(
-      getFuncAddr("strcasecmp", reinterpret_cast<uintptr_t>(&strcasecmp)));
-  REAL(strstr) = reinterpret_cast<strstr_type>(
-      getFuncAddr("strstr", reinterpret_cast<uintptr_t>(&strstr)));
-  REAL(strcasestr) = reinterpret_cast<strcasestr_type>(
-      getFuncAddr("strcasestr", reinterpret_cast<uintptr_t>(&strcasestr)));
-  REAL(memmem) = reinterpret_cast<memmem_type>(
-      getFuncAddr("memmem", reinterpret_cast<uintptr_t>(&memmem)));
-
-  FuzzerInitIsRunning = false;
-  FuzzerInited = 1;
-}
-
-#endif
index fa995a2..5657cab 100644 (file)
@@ -1,8 +1,4 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/MemcmpTest.cpp -o %t-MemcmpTest
 RUN: not %run %t-MemcmpTest               -seed=1 -runs=10000000   2>&1 | FileCheck %s
-
-RUN: %cpp_compiler -fno-sanitize=address %S/MemcmpTest.cpp -o %t-NoAsanMemcmpTest
-RUN: not %run %t-MemcmpTest               -seed=1 -runs=10000000   2>&1 | FileCheck %s
-
 CHECK: BINGO
index ca8c8fe..24d14bf 100644 (file)
@@ -1,8 +1,4 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/Memcmp64BytesTest.cpp -o %t-Memcmp64BytesTest
 RUN: not %run %t-Memcmp64BytesTest        -seed=1 -runs=1000000   2>&1 | FileCheck %s
-
-RUN: %cpp_compiler -fno-sanitize=address %S/Memcmp64BytesTest.cpp -o %t-NoAsanMemcmp64BytesTest
-RUN: not %run %t-Memcmp64BytesTest        -seed=1 -runs=1000000   2>&1 | FileCheck %s
-
 CHECK: BINGO
index 61065de..bd917bb 100644 (file)
@@ -1,8 +1,5 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/StrcmpTest.cpp -o %t-StrcmpTest
 RUN: not %run %t-StrcmpTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s
-
-RUN: %cpp_compiler -fno-sanitize=address %S/StrcmpTest.cpp -o %t-NoAsanStrcmpTest
-RUN: not %run %t-StrcmpTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s
-
 CHECK: BINGO
+
index 1024510..5018944 100644 (file)
@@ -1,8 +1,5 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/StrncmpTest.cpp -o %t-StrncmpTest
 RUN: not %run %t-StrncmpTest              -seed=2 -runs=10000000   2>&1 | FileCheck %s
-
-RUN: %cpp_compiler -fno-sanitize=address %S/StrncmpTest.cpp -o %t-NoAsanStrncmpTest
-RUN: not %run %t-StrncmpTest              -seed=2 -runs=10000000   2>&1 | FileCheck %s
-
 CHECK: BINGO
+
index 5c10805..f1fb210 100644 (file)
@@ -1,8 +1,5 @@
 UNSUPPORTED: freebsd
 RUN: %cpp_compiler %S/StrstrTest.cpp -o %t-StrstrTest
 RUN: not %run %t-StrstrTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s
-
-RUN: %cpp_compiler -fno-sanitize=address %S/StrstrTest.cpp -o %t-NoAsanStrstrTest
-RUN: not %run %t-StrstrTest               -seed=1 -runs=2000000   2>&1 | FileCheck %s
-
 CHECK: BINGO
+