From f2973dcfe834c476f66c2b36dfcd75bcf3e8d5d5 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Tue, 27 Dec 2016 21:13:11 +0000 Subject: [PATCH] [compiler-rt] Move logic which replace memcpy interceptor with memmove from asan to sanitizer_common. Reviewers: eugenis Subscribers: kubabrecka, dberris, llvm-commits Differential Revision: https://reviews.llvm.org/D28074 llvm-svn: 290626 --- compiler-rt/lib/asan/asan_interceptors.cc | 23 +--------- compiler-rt/lib/asan/asan_internal.h | 11 ----- compiler-rt/lib/asan/asan_mac.cc | 9 ---- compiler-rt/lib/msan/msan_interceptors.cc | 1 - .../sanitizer_common_interceptors.inc | 44 ++++++++++++++----- .../lib/sanitizer_common/sanitizer_mac.cc | 9 ++++ 6 files changed, 42 insertions(+), 55 deletions(-) diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc index 1ef3a4df04481..606016d4f4d38 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cc +++ b/compiler-rt/lib/asan/asan_interceptors.cc @@ -250,20 +250,10 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) ASAN_MEMMOVE_IMPL(ctx, to, from, size); \ } while (false) -// 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. #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \ do { \ ASAN_INTERCEPTOR_ENTER(ctx, memcpy); \ - if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \ - ASAN_MEMCPY_IMPL(ctx, to, from, size); \ - } else { \ - ASAN_MEMMOVE_IMPL(ctx, to, from, size); \ - } \ + ASAN_MEMCPY_IMPL(ctx, to, from, size); \ } while (false) #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \ @@ -272,17 +262,6 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) ASAN_MEMSET_IMPL(ctx, block, c, size); \ } while (false) -// In asan, REAL(memmove) is not used, but it is used in msan. -#define COMMON_INTERCEPT_FUNCTION_MEMCPY() \ - do { \ - if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \ - ASAN_INTERCEPT_FUNC(memcpy); \ - } else { \ - ASSIGN_REAL(memcpy, memmove); \ - } \ - CHECK(REAL(memcpy)); \ - } while (false) - #include "sanitizer_common/sanitizer_common_interceptors.inc" // Syscall interceptors don't have contexts, we don't support suppressions diff --git a/compiler-rt/lib/asan/asan_internal.h b/compiler-rt/lib/asan/asan_internal.h index a3fe062f73fc9..1dc678c0c3579 100644 --- a/compiler-rt/lib/asan/asan_internal.h +++ b/compiler-rt/lib/asan/asan_internal.h @@ -103,17 +103,6 @@ void *AsanDlSymNext(const char *sym); void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name); -// Platform-specific options. -#if SANITIZER_MAC -bool PlatformHasDifferentMemcpyAndMemmove(); -# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \ - (PlatformHasDifferentMemcpyAndMemmove()) -#elif SANITIZER_WINDOWS64 -# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false -#else -# define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true -#endif // SANITIZER_MAC - // Add convenient macro for interface functions that may be represented as // weak hooks. #define ASAN_MALLOC_HOOK(ptr, size) \ diff --git a/compiler-rt/lib/asan/asan_mac.cc b/compiler-rt/lib/asan/asan_mac.cc index 525864f72d32d..baf533ac96aca 100644 --- a/compiler-rt/lib/asan/asan_mac.cc +++ b/compiler-rt/lib/asan/asan_mac.cc @@ -49,15 +49,6 @@ namespace __asan { void InitializePlatformInterceptors() {} void InitializePlatformExceptionHandlers() {} -bool PlatformHasDifferentMemcpyAndMemmove() { - // On OS X 10.7 memcpy() and memmove() are both resolved - // into memmove$VARIANT$sse42. - // See also https://github.com/google/sanitizers/issues/34. - // TODO(glider): need to check dynamically that memcpy() and memmove() are - // actually the same function. - return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD; -} - // No-op. Mac does not support static linkage anyway. void *AsanDoesNotSupportStaticLinkage() { return 0; diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index 89ae45998c16a..6447bb1b270e8 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -1291,7 +1291,6 @@ int OnExit() { } while (0) #define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name) -#define COMMON_INTERCEPT_FUNCTION_MEMCPY() MSAN_INTERCEPT_FUNC(memcpy) #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ MSAN_INTERCEPT_FUNC_VER(name, ver) #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 7213c9a9720ce..1d58205e78610 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -70,6 +70,17 @@ #define iconv __bsd_iconv #endif +// Platform-specific options. +#if SANITIZER_MAC +bool PlatformHasDifferentMemcpyAndMemmove(); +#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \ + (PlatformHasDifferentMemcpyAndMemmove()) +#elif SANITIZER_WINDOWS64 +#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false +#else +#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true +#endif // SANITIZER_MAC + #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {} #endif @@ -192,11 +203,6 @@ } #endif -// On OS X, calling internal_memcpy here will cause memory corruptions, -// because memcpy and memmove are actually aliases of the same -// implementation. We need to use internal_memmove here. -// N.B.: If we switch this to internal_ we'll have to use internal_memmove -// due to memcpy being an alias of memmove on OS X. #ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \ { \ @@ -212,10 +218,6 @@ } #endif -#ifndef COMMON_INTERCEPT_FUNCTION_MEMCPY -#define COMMON_INTERCEPT_FUNCTION_MEMCPY() {} -#endif - struct FileMetadata { // For open_memstream(). char **addr; @@ -641,11 +643,29 @@ INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { #if SANITIZER_INTERCEPT_MEMCPY INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { - void *ctx; - COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size); + // On OS X, calling internal_memcpy here will cause memory corruptions, + // because memcpy and memmove are actually aliases of the same + // implementation. We need to use internal_memmove here. + // N.B.: If we switch this to internal_ we'll have to use internal_memmove + // due to memcpy being an alias of memmove on OS X. + void *ctx; + if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { + COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size); + } else { + COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); + } } -#define INIT_MEMCPY COMMON_INTERCEPT_FUNCTION_MEMCPY() +#define INIT_MEMCPY \ + do { \ + if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \ + COMMON_INTERCEPT_FUNCTION(memcpy); \ + } else { \ + ASSIGN_REAL(memcpy, memmove); \ + } \ + CHECK(REAL(memcpy)); \ + } while (false) + #else #define INIT_MEMCPY #endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc index cf9465b33f761..73e018c857e87 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc @@ -448,6 +448,15 @@ MacosVersion GetMacosVersion() { return result; } +bool PlatformHasDifferentMemcpyAndMemmove() { + // On OS X 10.7 memcpy() and memmove() are both resolved + // into memmove$VARIANT$sse42. + // See also https://github.com/google/sanitizers/issues/34. + // TODO(glider): need to check dynamically that memcpy() and memmove() are + // actually the same function. + return GetMacosVersion() == MACOS_VERSION_SNOW_LEOPARD; +} + uptr GetRSS() { struct task_basic_info info; unsigned count = TASK_BASIC_INFO_COUNT;