[compiler-rt] r191081 - [ASan] Enforce the memmove semantics for both memcpy() and memmove() interceptors on Darwin.

Alexander Potapenko glider at google.com
Fri Sep 20 03:56:34 PDT 2013


Author: glider
Date: Fri Sep 20 05:56:34 2013
New Revision: 191081

URL: http://llvm.org/viewvc/llvm-project?rev=191081&view=rev
Log:
[ASan] Enforce the memmove semantics for both memcpy() and memmove() interceptors on Darwin.

Due to bugs in the interposition of resolver functions on 10.7 and 10.8 both memcpy() and memmove()
were previously intercepted by INTERCEPTOR(memcpy), which led to false positives and crashes (see http://llvm.org/bugs/show_bug.cgi?id=16362)
We choose to use a memmove-like function in both cases. This effectively disables the overlap checks in memcpy(), but the overlaps
aren't possible in practice, because memcpy() and memmove() are the same function on Darwin.

Once the interposition is fixed in 10.9, we'll need to revisit this issue, see https://code.google.com/p/address-sanitizer/issues/detail?id=226

Modified:
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/tests/asan_str_test.cc

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=191081&r1=191080&r2=191081&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Fri Sep 20 05:56:34 2013
@@ -315,7 +315,26 @@ INTERCEPTOR(int, memcmp, const void *a1,
   return REAL(memcmp(a1, a2, size));
 }
 
+#define MEMMOVE_BODY { \
+  if (!asan_inited) return internal_memmove(to, from, size); \
+  if (asan_init_is_running) { \
+    return REAL(memmove)(to, from, size); \
+  } \
+  ENSURE_ASAN_INITED(); \
+  if (flags()->replace_intrin) { \
+    ASAN_READ_RANGE(from, size); \
+    ASAN_WRITE_RANGE(to, size); \
+  } \
+  /* Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. \
+     See also \
+     http://code.google.com/p/address-sanitizer/issues/detail?id=116. */ \
+  return internal_memmove(to, from, size); \
+}
+
+INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) MEMMOVE_BODY
+
 INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {
+#if !SANITIZER_MAC
   if (!asan_inited) return internal_memcpy(to, from, size);
   // memcpy is called during __asan_init() from the internals
   // of printf(...).
@@ -332,24 +351,19 @@ INTERCEPTOR(void*, memcpy, void *to, con
     ASAN_READ_RANGE(from, size);
     ASAN_WRITE_RANGE(to, size);
   }
-  // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8.
+  // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8, so
+  // calling REAL(memcpy) here leads to infinite recursion.
   // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116.
   return internal_memcpy(to, from, size);
-}
-
-INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {
-  if (!asan_inited) return internal_memmove(to, from, size);
-  if (asan_init_is_running) {
-    return REAL(memmove)(to, from, size);
-  }
-  ENSURE_ASAN_INITED();
-  if (flags()->replace_intrin) {
-    ASAN_READ_RANGE(from, size);
-    ASAN_WRITE_RANGE(to, size);
-  }
-  // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8.
-  // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116.
-  return internal_memmove(to, from, size);
+#else
+  // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced
+  // with WRAP(memcpy). As a result, false positives are reported for memmove()
+  // calls. If we just disable error reporting with
+  // ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with
+  // internal_memcpy(), which may lead to crashes, see
+  // http://llvm.org/bugs/show_bug.cgi?id=16362.
+  MEMMOVE_BODY
+#endif  // !SANITIZER_MAC
 }
 
 INTERCEPTOR(void*, memset, void *block, int c, uptr size) {

Modified: compiler-rt/trunk/lib/asan/tests/asan_str_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_str_test.cc?rev=191081&r1=191080&r2=191081&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_str_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_str_test.cc Fri Sep 20 05:56:34 2013
@@ -12,6 +12,8 @@
 //===----------------------------------------------------------------------===//
 #include "asan_test_utils.h"
 
+#include <AvailabilityMacros.h>
+
 // Used for string functions tests
 static char global_string[] = "global";
 static size_t global_string_length = 6;





More information about the llvm-commits mailing list