Index: lib/asan/asan_interceptors.cc =================================================================== --- lib/asan/asan_interceptors.cc +++ lib/asan/asan_interceptors.cc @@ -250,20 +250,10 @@ 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 @@ 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 Index: lib/asan/asan_internal.h =================================================================== --- lib/asan/asan_internal.h +++ lib/asan/asan_internal.h @@ -103,17 +103,6 @@ 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) \ Index: lib/asan/asan_mac.cc =================================================================== --- lib/asan/asan_mac.cc +++ lib/asan/asan_mac.cc @@ -49,15 +49,6 @@ 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; Index: lib/asan/tests/asan_asm_test.cc =================================================================== --- lib/asan/tests/asan_asm_test.cc +++ lib/asan/tests/asan_asm_test.cc @@ -57,12 +57,13 @@ return res; \ } -#define DECLARE_ASM_REP_MOVS(Type, Movs) \ - template <> void asm_rep_movs(Type * dst, Type * src, size_t size) { \ - __asm__("rep " Movs " \n\t" \ - : \ - : "D"(dst), "S"(src), "c"(size) \ - : "rsi", "rdi", "rcx", "memory"); \ +#define DECLARE_ASM_REP_MOVS(Type, Movs) \ + template <> \ + void asm_rep_movs(Type * dst, Type * src, size_t size) { \ + __asm__("rep " Movs " \n\t" \ + : "+D"(dst), "+S"(src), "+c"(size) \ + : \ + : "memory"); \ } DECLARE_ASM_WRITE(U8, "8", "movq", "r"); @@ -99,12 +100,13 @@ return res; \ } -#define DECLARE_ASM_REP_MOVS(Type, Movs) \ - template <> void asm_rep_movs(Type * dst, Type * src, size_t size) { \ - __asm__("rep " Movs " \n\t" \ - : \ - : "D"(dst), "S"(src), "c"(size) \ - : "esi", "edi", "ecx", "memory"); \ +#define DECLARE_ASM_REP_MOVS(Type, Movs) \ + template <> \ + void asm_rep_movs(Type * dst, Type * src, size_t size) { \ + __asm__("rep " Movs " \n\t" \ + : "+D"(dst), "+S"(src), "+c"(size) \ + : \ + : "memory"); \ } } // End of anonymous namespace Index: lib/msan/msan_interceptors.cc =================================================================== --- lib/msan/msan_interceptors.cc +++ lib/msan/msan_interceptors.cc @@ -1291,7 +1291,6 @@ } 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) \ Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -70,6 +70,19 @@ #define iconv __bsd_iconv #endif +// Platform-specific options. +#if SANITIZER_MAC +namespace __sanitizer { +bool PlatformHasDifferentMemcpyAndMemmove(); +} +#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \ + (__sanitizer::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 +205,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 +220,6 @@ } #endif -#ifndef COMMON_INTERCEPT_FUNCTION_MEMCPY -#define COMMON_INTERCEPT_FUNCTION_MEMCPY() {} -#endif - struct FileMetadata { // For open_memstream(). char **addr; @@ -641,11 +645,29 @@ #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 Index: lib/sanitizer_common/sanitizer_common_interceptors_format.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors_format.inc +++ lib/sanitizer_common/sanitizer_common_interceptors_format.inc @@ -435,10 +435,6 @@ } static int printf_get_value_size(PrintfDirective *dir) { - if (dir->convSpecifier == 'm') { - return sizeof(char *); - } - if (char_is_one_of(dir->convSpecifier, "cCsS")) { unsigned charSize = format_get_char_size(dir->convSpecifier, dir->lengthModifier); @@ -519,6 +515,9 @@ // Dynamic precision SKIP_SCALAR_ARG(&aq, 'd', sizeof(int)); } + // %m does not require an argument: strlen(errno). + if (dir.convSpecifier == 'm') + continue; int size = printf_get_value_size(&dir); if (size == FSS_INVALID) { Report("WARNING: unexpected format specifier in printf " Index: lib/sanitizer_common/sanitizer_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_mac.cc +++ lib/sanitizer_common/sanitizer_mac.cc @@ -448,6 +448,15 @@ 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; Index: lib/sanitizer_common/sanitizer_procmaps_mac.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_mac.cc +++ lib/sanitizer_common/sanitizer_procmaps_mac.cc @@ -19,6 +19,20 @@ #include #include +// These are not available in older macOS SDKs. +#ifndef CPU_SUBTYPE_X86_64_H +#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8) /* Haswell */ +#endif +#ifndef CPU_SUBTYPE_ARM_V7S +#define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t)11) /* Swift */ +#endif +#ifndef CPU_SUBTYPE_ARM_V7K +#define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t)12) +#endif +#ifndef CPU_TYPE_ARM64 +#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) +#endif + namespace __sanitizer { MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) { Index: lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc =================================================================== --- lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc +++ lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc @@ -256,4 +256,8 @@ // Checks for wide-character strings are not implemented yet. testPrintf("%ls", 1, 0); + + testPrintf("%m", 0); + testPrintf("%m%s", 1, test_buf_size); + testPrintf("%s%m%s", 2, test_buf_size, test_buf_size); } Index: lib/tsan/tests/rtl/tsan_test_util_posix.cc =================================================================== --- lib/tsan/tests/rtl/tsan_test_util_posix.cc +++ lib/tsan/tests/rtl/tsan_test_util_posix.cc @@ -60,11 +60,11 @@ if (rep->typ != expect_report_type) { printf("Expected report of type %d, got type %d\n", (int)expect_report_type, (int)rep->typ); - EXPECT_FALSE("Wrong report type"); + EXPECT_TRUE(false) << "Wrong report type"; return false; } } else { - EXPECT_FALSE("Unexpected report"); + EXPECT_TRUE(false) << "Unexpected report"; return false; } expect_report_reported = true; @@ -323,7 +323,7 @@ } if (expect_report && !expect_report_reported) { printf("Missed expected report of type %d\n", (int)ev->report_type); - EXPECT_FALSE("Missed expected race"); + EXPECT_TRUE(false) << "Missed expected race"; } expect_report = false; } Index: lib/xray/xray_inmemory_log.cc =================================================================== --- lib/xray/xray_inmemory_log.cc +++ lib/xray/xray_inmemory_log.cc @@ -112,14 +112,23 @@ // Open a temporary file once for the log. static char TmpFilename[256] = {}; static char TmpWildcardPattern[] = "XXXXXX"; - auto E = internal_strncat(TmpFilename, flags()->xray_logfile_base, - sizeof(TmpFilename) - 10); - if (static_cast((E + 6) - TmpFilename) > (sizeof(TmpFilename) - 1)) { - Report("XRay log file base too long: %s\n", flags()->xray_logfile_base); + auto Argv = GetArgv(); + const char *Progname = Argv[0] == nullptr ? "(unknown)" : Argv[0]; + const char *LastSlash = internal_strrchr(Progname, '/'); + + if (LastSlash != nullptr) + Progname = LastSlash + 1; + + const int HalfLength = sizeof(TmpFilename) / 2 - sizeof(TmpWildcardPattern); + int NeededLength = internal_snprintf(TmpFilename, sizeof(TmpFilename), + "%.*s%.*s.%s", + HalfLength, flags()->xray_logfile_base, + HalfLength, Progname, + TmpWildcardPattern); + if (NeededLength > int(sizeof(TmpFilename))) { + Report("XRay log file name too long (%d): %s\n", NeededLength, TmpFilename); return -1; } - internal_strncat(TmpFilename, TmpWildcardPattern, - sizeof(TmpWildcardPattern) - 1); int Fd = mkstemp(TmpFilename); if (Fd == -1) { Report("XRay: Failed opening temporary file '%s'; not logging events.\n", Index: test/asan/TestCases/printf-m.c =================================================================== --- /dev/null +++ test/asan/TestCases/printf-m.c @@ -0,0 +1,14 @@ +// RUN: %clang_asan -O2 %s -o %t && %run %t + +// FIXME: printf is not intercepted on Windows yet. +// UNSUPPORTED: win32 + +#include + +int main() { + char s[5] = {'w', 'o', 'r', 'l', 'd'}; + // Test that %m does not consume an argument. If it does, %s would apply to + // the 5-character buffer, resulting in a stack-buffer-overflow report. + printf("%m %s, %.5s\n", "hello", s); + return 0; +} Index: test/asan/TestCases/sanity_check_pure_c.c =================================================================== --- test/asan/TestCases/sanity_check_pure_c.c +++ test/asan/TestCases/sanity_check_pure_c.c @@ -3,7 +3,7 @@ // RUN: not %run %t 2>&1 | FileCheck %s // Sanity checking a test in pure C with -pie. -// RUN: %clang_asan -O2 %s -pie -fPIE -o %t +// RUN: %clang_asan -O2 %s %pie %fPIE -o %t // RUN: not %run %t 2>&1 | FileCheck %s // REQUIRES: stable-runtime Index: test/asan/TestCases/suppressions-library.cc =================================================================== --- test/asan/TestCases/suppressions-library.cc +++ test/asan/TestCases/suppressions-library.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %dynamiclib %ld_flags_rpath_so +// RUN: %clangxx_asan -O0 -DSHARED_LIB %s %fPIC -shared -o %dynamiclib %ld_flags_rpath_so // RUN: %clangxx_asan -O0 %s -o %t %ld_flags_rpath_exe // Check that without suppressions, we catch the issue. Index: test/asan/lit.cfg =================================================================== --- test/asan/lit.cfg +++ test/asan/lit.cfg @@ -229,6 +229,15 @@ if config.host_os == 'Darwin': config.suffixes.append('.mm') +if config.host_os == 'Windows': + config.substitutions.append(('%fPIC', '')) + config.substitutions.append(('%fPIE', '')) + config.substitutions.append(('%pie', '')) +else: + config.substitutions.append(('%fPIC', '-fPIC')) + config.substitutions.append(('%fPIE', '-fPIE')) + config.substitutions.append(('%pie', '-pie')) + # Only run the tests on supported OSs. if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows']: config.unsupported = True Index: test/scudo/CMakeLists.txt =================================================================== --- test/scudo/CMakeLists.txt +++ test/scudo/CMakeLists.txt @@ -17,16 +17,7 @@ foreach(arch ${SCUDO_TEST_ARCH}) set(SCUDO_TEST_TARGET_ARCH ${arch}) string(TOLOWER "-${arch}" SCUDO_TEST_CONFIG_SUFFIX) - - if(ANDROID OR ${arch} MATCHES "arm|aarch64") - # This is only true if we are cross-compiling. - # Build all tests with host compiler and use host tools. - set(SCUDO_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS}) - else() - get_target_flags_for_arch(${arch} SCUDO_TEST_TARGET_CFLAGS) - string(REPLACE ";" " " SCUDO_TEST_TARGET_CFLAGS "${SCUDO_TEST_TARGET_CFLAGS}") - endif() - + get_test_cc_for_arch(${arch} SCUDO_TEST_TARGET_CC SCUDO_TEST_TARGET_CFLAGS) string(TOUPPER ${arch} ARCH_UPPER_CASE) set(CONFIG_NAME ${ARCH_UPPER_CASE}${OS_NAME}Config) Index: test/xray/TestCases/Linux/fixedsize-logging.cc =================================================================== --- test/xray/TestCases/Linux/fixedsize-logging.cc +++ test/xray/TestCases/Linux/fixedsize-logging.cc @@ -2,6 +2,7 @@ // RUN: %clangxx_xray -std=c++11 %s -o %t // RUN: XRAY_OPTIONS="verbosity=1 xray_logfile_base=fixedsize-logging-" %run %t 2>&1 | FileCheck %s +// RUN: ls -la fixedsize-logging-$(basename %t).?????? 2>&1 // // After all that, clean up the output xray log. //