[compiler-rt] r275621 - [sanitizers] add interceptor for memmem; add weak hooks for strncasecmp, strcasecmp, strstr, strcasestr, memmem

Kostya Serebryany via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 15 14:28:59 PDT 2016


Author: kcc
Date: Fri Jul 15 16:28:58 2016
New Revision: 275621

URL: http://llvm.org/viewvc/llvm-project?rev=275621&view=rev
Log:
[sanitizers] add interceptor for memmem; add weak hooks for strncasecmp, strcasecmp, strstr, strcasestr, memmem

Added:
    compiler-rt/trunk/test/asan/TestCases/memmem_test.cc
    compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/weak_hook_test.cc
Modified:
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h

Modified: compiler-rt/trunk/include/sanitizer/common_interface_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=275621&r1=275620&r2=275621&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Fri Jul 15 16:28:58 2016
@@ -131,8 +131,19 @@ extern "C" {
                                     const void *s2, size_t n, int result);
   void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
                                     const char *s2, size_t n, int result);
+  void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+                                         const char *s2, size_t n, int result);
   void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
                                     const char *s2, int result);
+  void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+                                        const char *s2, int result);
+  void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+                                    const char *s2, char *result);
+  void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+                                        const char *s2, char *result);
+  void __sanitizer_weak_hook_memmem(void *called_pc,
+                                    const void *s1, size_t len1,
+                                    const void *s2, size_t len2, void *result);
 
   // Prints stack traces for all live heap allocations ordered by total
   // allocation size until `top_percent` of total live heap is shown.

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=275621&r1=275620&r2=275621&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Fri Jul 15 16:28:58 2016
@@ -326,6 +326,9 @@ static inline int CharCaseCmp(unsigned c
   return c1_low - c2_low;
 }
 
+DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,
+                              const char *s1, const char *s2, int result)
+
 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
@@ -338,9 +341,16 @@ INTERCEPTOR(int, strcasecmp, const char
   }
   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
-  return CharCaseCmp(c1, c2);
+  int result = CharCaseCmp(c1, c2);
+  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),
+                             s1, s2, result);
+  return result;
 }
 
+DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,
+                              const char *s1, const char *s2, uptr n,
+                              int result)
+
 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
@@ -353,7 +363,10 @@ INTERCEPTOR(int, strncasecmp, const char
   }
   COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
   COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
-  return CharCaseCmp(c1, c2);
+  int result = CharCaseCmp(c1, c2);
+  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),
+                             s1, s2, n, result);
+  return result;
 }
 
 #define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
@@ -375,6 +388,10 @@ static inline void StrstrCheck(void *ctx
 #endif
 
 #if SANITIZER_INTERCEPT_STRSTR
+
+DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,
+                              const char *s1, const char *s2, char *result);
+
 INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
     return internal_strstr(s1, s2);
@@ -383,6 +400,8 @@ INTERCEPTOR(char*, strstr, const char *s
   char *r = REAL(strstr)(s1, s2);
   if (common_flags()->intercept_strstr)
     StrstrCheck(ctx, r, s1, s2);
+  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,
+                             s2, r);
   return r;
 }
 
@@ -392,12 +411,18 @@ INTERCEPTOR(char*, strstr, const char *s
 #endif
 
 #if SANITIZER_INTERCEPT_STRCASESTR
+
+DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,
+                              const char *s1, const char *s2, char *result);
+
 INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
   char *r = REAL(strcasestr)(s1, s2);
   if (common_flags()->intercept_strstr)
     StrstrCheck(ctx, r, s1, s2);
+  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),
+                             s1, s2, r);
   return r;
 }
 
@@ -406,6 +431,30 @@ INTERCEPTOR(char*, strcasestr, const cha
 #define INIT_STRCASESTR
 #endif
 
+#if SANITIZER_INTERCEPT_MEMMEM
+DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,
+                              const void *s1, SIZE_T len1, const void *s2,
+                              SIZE_T len2, void *result);
+
+INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,
+            SIZE_T len2) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);
+  void *r = REAL(memmem)(s1, len1, s2, len2);
+  if (common_flags()->intercept_memmem) {
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);
+    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);
+  }
+  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),
+                             s1, len1, s2, len2, r);
+  return r;
+}
+
+#define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);
+#else
+#define INIT_MEMMEM
+#endif  // SANITIZER_INTERCEPT_MEMMEM
+
 #if SANITIZER_INTERCEPT_STRCHR
 INTERCEPTOR(char*, strchr, const char *s, int c) {
   void *ctx;
@@ -5830,6 +5879,7 @@ static void InitializeCommonInterceptors
   INIT_MEMCHR;
   INIT_MEMCMP;
   INIT_MEMRCHR;
+  INIT_MEMMEM;
   INIT_READ;
   INIT_PREAD;
   INIT_PREAD64;

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc?rev=275621&r1=275620&r2=275621&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_flags.inc Fri Jul 15 16:28:58 2016
@@ -199,6 +199,8 @@ COMMON_FLAG(bool, intercept_memcmp, true
 COMMON_FLAG(bool, strict_memcmp, true,
           "If true, assume that memcmp(p1, p2, n) always reads n bytes before "
           "comparing p1 and p2.")
+COMMON_FLAG(bool, intercept_memmem, true,
+            "If set, uses a wrapper for memmem() to find more errors.")
 COMMON_FLAG(bool, intercept_intrin, true,
             "If set, uses custom wrappers for memset/memcpy/memmove "
             "intrinsics to find more errors.")

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=275621&r1=275620&r2=275621&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Fri Jul 15 16:28:58 2016
@@ -83,6 +83,7 @@
 #define SANITIZER_INTERCEPT_MEMMOVE 1
 #define SANITIZER_INTERCEPT_MEMCPY 1
 #define SANITIZER_INTERCEPT_MEMCMP 1
+#define SANITIZER_INTERCEPT_MEMMEM 1
 // The function memchr() contains a jump in the first 6 bytes
 // that is problematic to intercept correctly on Win64.
 // Disable memchr() interception for Win64.

Added: compiler-rt/trunk/test/asan/TestCases/memmem_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/memmem_test.cc?rev=275621&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/memmem_test.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/memmem_test.cc Fri Jul 15 16:28:58 2016
@@ -0,0 +1,21 @@
+// RUN: %clangxx_asan  %s -o %t
+// RUN: not %run %t   2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=A1
+// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=A2
+// RUN: %env_asan_opts=intercept_memmem=0 %run %t
+
+#include <string.h>
+int main(int argc, char **argv) {
+  char a1[] = {1, 2, 3, 4, 5, 6, 7, 8};
+  char a2[] = {3, 4, 5};
+  void *res;
+  if (argc == 1)
+    res = memmem(a1, sizeof(a1) + 1, a2, sizeof(a2));  // BOOM
+  else
+    res = memmem(a1, sizeof(a1), a2, sizeof(a2) + 1);  // BOOM
+  // CHECK: AddressSanitizer: stack-buffer-overflow
+  // CHECK: {{#0.*memmem}}
+  // CHECK: {{#1.*main}}
+  // A1: 'a1' <== Memory access at offset
+  // A2: 'a2' <== Memory access at offset
+  return res == NULL;
+}

Added: compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/weak_hook_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/weak_hook_test.cc?rev=275621&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/weak_hook_test.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/Linux/weak_hook_test.cc Fri Jul 15 16:28:58 2016
@@ -0,0 +1,82 @@
+// Test the weak hooks.
+// RUN: %clangxx %s -o %t
+// RUN: %run %t
+
+// Hooks are not implemented for lsan.
+// XFAIL: lsan
+
+#include <string.h>
+#include <assert.h>
+
+bool seen_memcmp, seen_strncmp, seen_strncasecmp, seen_strcmp, seen_strcasecmp,
+    seen_strstr, seen_strcasestr, seen_memmem;
+
+extern "C" {
+void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
+                                  const void *s2, size_t n, int result) {
+  seen_memcmp = true;
+}
+void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
+                                   const char *s2, size_t n, int result) {
+  seen_strncmp = true;
+}
+void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+                                       const char *s2, size_t n, int result){
+  seen_strncasecmp = true;
+}
+void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
+                                  const char *s2, int result){
+  seen_strcmp = true;
+}
+void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+                                      const char *s2, int result){
+  seen_strcasecmp = true;
+}
+void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+                                  const char *s2, char *result){
+  seen_strstr = true;
+}
+void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+                                      const char *s2, char *result){
+  seen_strcasestr = true;
+}
+void __sanitizer_weak_hook_memmem(void *called_pc, const void *s1, size_t len1,
+                                  const void *s2, size_t len2, void *result){
+  seen_memmem = true;
+}
+} // extern "C"
+
+char s1[] = "ABCDEF";
+char s2[] = "CDE";
+
+static volatile int int_sink;
+static volatile void *ptr_sink;
+
+int main() {
+  assert(sizeof(s2) < sizeof(s1));
+
+  int_sink = memcmp(s1, s2, sizeof(s2));
+  assert(seen_memcmp);
+
+  int_sink = strncmp(s1, s2, sizeof(s2));
+  assert(seen_strncmp);
+
+  int_sink = strncasecmp(s1, s2, sizeof(s2));
+  assert(seen_strncasecmp);
+
+  int_sink = strcmp(s1, s2);
+  assert(seen_strcmp);
+
+  int_sink = strcasecmp(s1, s2);
+  assert(seen_strcasecmp);
+
+  ptr_sink = strstr(s1, s2);
+  assert(seen_strstr);
+
+  ptr_sink = strcasestr(s1, s2);
+  assert(seen_strcasestr);
+
+  ptr_sink = memmem(s1, sizeof(s1), s2, sizeof(s2));
+  assert(seen_memmem);
+  return 0;
+}




More information about the llvm-commits mailing list