diff options
Diffstat (limited to 'lib/asan/tests')
-rw-r--r-- | lib/asan/tests/CMakeLists.txt | 219 | ||||
-rw-r--r-- | lib/asan/tests/asan_asm_test.cc | 267 | ||||
-rw-r--r-- | lib/asan/tests/asan_fake_stack_test.cc | 10 | ||||
-rw-r--r-- | lib/asan/tests/asan_interface_test.cc | 67 | ||||
-rw-r--r-- | lib/asan/tests/asan_mem_test.cc | 15 | ||||
-rw-r--r-- | lib/asan/tests/asan_noinst_test.cc | 110 | ||||
-rw-r--r-- | lib/asan/tests/asan_oob_test.cc | 4 | ||||
-rw-r--r-- | lib/asan/tests/asan_racy_double_free_test.cc | 4 | ||||
-rw-r--r-- | lib/asan/tests/asan_str_test.cc | 52 | ||||
-rw-r--r-- | lib/asan/tests/asan_test.cc | 193 | ||||
-rw-r--r-- | lib/asan/tests/asan_test_config.h | 12 | ||||
-rw-r--r-- | lib/asan/tests/asan_test_utils.h | 20 |
12 files changed, 678 insertions, 295 deletions
diff --git a/lib/asan/tests/CMakeLists.txt b/lib/asan/tests/CMakeLists.txt index fc0f1788bd354..7b363714e8a53 100644 --- a/lib/asan/tests/CMakeLists.txt +++ b/lib/asan/tests/CMakeLists.txt @@ -15,32 +15,29 @@ include(CompilerRTCompile) include_directories(..) include_directories(../..) -# Use zero-based shadow on Android. -if(ANDROID) - set(ASAN_TESTS_USE_ZERO_BASE_SHADOW TRUE) -else() - set(ASAN_TESTS_USE_ZERO_BASE_SHADOW FALSE) -endif() - set(ASAN_UNITTEST_HEADERS asan_mac_test.h asan_test_config.h asan_test_utils.h) set(ASAN_UNITTEST_COMMON_CFLAGS - ${COMPILER_RT_GTEST_INCLUDE_CFLAGS} + ${COMPILER_RT_TEST_CFLAGS} + ${COMPILER_RT_GTEST_CFLAGS} -I${COMPILER_RT_SOURCE_DIR}/include -I${COMPILER_RT_SOURCE_DIR}/lib -I${COMPILER_RT_SOURCE_DIR}/lib/asan -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests - -Wall + -fno-rtti + -O2 -Wno-format - -Werror - -Werror=sign-compare - -g - -O2) -if(SUPPORTS_NO_VARIADIC_MACROS_FLAG) - list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -Wno-variadic-macros) + -Werror=sign-compare) +append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS) + +# -gline-tables-only must be enough for ASan, so use it if possible. +if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang") + list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only) +else() + list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g) endif() # Use -D instead of definitions to please custom compile command. @@ -48,79 +45,91 @@ list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -DASAN_HAS_BLACKLIST=1 -DASAN_HAS_EXCEPTIONS=1 -DASAN_UAR=0) -if(ANDROID) - list(APPEND ASAN_UNITTEST_COMMON_CFLAGS - -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=0 - -DASAN_NEEDS_SEGV=0) -else() - list(APPEND ASAN_UNITTEST_COMMON_CFLAGS - -DASAN_FLEXIBLE_MAPPING_AND_OFFSET=1 - -DASAN_NEEDS_SEGV=1) -endif() set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore") set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS ${ASAN_UNITTEST_COMMON_CFLAGS} -fsanitize=address "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}" - -mllvm -asan-stack=1 - -mllvm -asan-globals=1 - -mllvm -asan-mapping-scale=0 # default will be used - -mllvm -asan-mapping-offset-log=-1 # default will be used ) -if(ASAN_TESTS_USE_ZERO_BASE_SHADOW) - list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS - -fsanitize-address-zero-base-shadow) +if(CAN_TARGET_x86_64 OR CAN_TARGET_i386) + list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly) +endif() + +if(NOT MSVC) + list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++) +endif() + +# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. +if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE") + list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++") endif() -# Unit tests require libstdc++. -set(ASAN_UNITTEST_COMMON_LINKFLAGS -lstdc++) # Unit tests on Mac depend on Foundation. if(APPLE) list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation) endif() -if(ASAN_TESTS_USE_ZERO_BASE_SHADOW) +if(ANDROID) list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie) endif() set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS}) -# On Android, we link with ASan runtime manually. On other platforms we depend -# on Clang driver behavior, passing -fsanitize=address flag. -if(NOT ANDROID) - list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address) -endif() +list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address) -set(ASAN_UNITTEST_NOINST_LINKFLAGS - ${ASAN_UNITTEST_COMMON_LINKFLAGS} - -ldl -lm) -if(NOT ANDROID) - list(APPEND ASAN_UNITTEST_NOINST_LINKFLAGS -lpthread) -endif() +set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS + ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS} + -shared-libasan) + +set(ASAN_UNITTEST_INSTRUMENTED_LIBS) +# NDK r10 requires -latomic almost always. +append_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS) + +set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS}) +append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS) +append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS) +append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS) +append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread + ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS) + +# TODO(eugenis): move all -l flags above to _LIBS? +set(ASAN_UNITTEST_NOINST_LIBS) +append_list_if(ANDROID log ASAN_UNITTEST_NOINST_LIBS) +# NDK r10 requires -latomic almost always. +append_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS) # Compile source for the given architecture, using compiler # options in ${ARGN}, and add it to the object list. -macro(asan_compile obj_list source arch) +macro(asan_compile obj_list source arch kind) get_filename_component(basename ${source} NAME) - set(output_obj "${obj_list}.${basename}.${arch}.o") + set(output_obj "${obj_list}.${basename}.${arch}${kind}.o") get_target_flags_for_arch(${arch} TARGET_CFLAGS) + set(COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE}) + if(NOT COMPILER_RT_STANDALONE_BUILD) + list(APPEND COMPILE_DEPS gtest asan) + endif() clang_compile(${output_obj} ${source} CFLAGS ${ARGN} ${TARGET_CFLAGS} - DEPS gtest asan_runtime_libraries - ${ASAN_UNITTEST_HEADERS} - ${ASAN_BLACKLIST_FILE}) + DEPS ${COMPILE_DEPS}) list(APPEND ${obj_list} ${output_obj}) endmacro() # Link ASan unit test for a given architecture from a set # of objects in with given linker flags. -macro(add_asan_test test_suite test_name arch) +macro(add_asan_test test_suite test_name arch kind) parse_arguments(TEST "OBJECTS;LINKFLAGS" "WITH_TEST_RUNTIME" ${ARGN}) get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS) - set(TEST_DEPS asan_runtime_libraries ${TEST_OBJECTS}) + set(TEST_DEPS ${TEST_OBJECTS}) + if(NOT COMPILER_RT_STANDALONE_BUILD) + list(APPEND TEST_DEPS asan) + endif() if(TEST_WITH_TEST_RUNTIME) list(APPEND TEST_DEPS ${ASAN_TEST_RUNTIME}) - list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a) + if(NOT MSVC) + list(APPEND TEST_OBJECTS lib${ASAN_TEST_RUNTIME}.a) + else() + list(APPEND TEST_OBJECTS ${ASAN_TEST_RUNTIME}.lib) + endif() endif() add_compiler_rt_test(${test_suite} ${test_name} OBJECTS ${TEST_OBJECTS} @@ -144,6 +153,7 @@ set(ASAN_NOINST_TEST_SOURCES set(ASAN_INST_TEST_SOURCES ${COMPILER_RT_GTEST_SOURCE} + asan_asm_test.cc asan_globals_test.cc asan_interface_test.cc asan_test.cc @@ -157,27 +167,32 @@ endif() set(ASAN_BENCHMARKS_SOURCES ${COMPILER_RT_GTEST_SOURCE} - asan_benchmarks_test.cc) + asan_benchmarks_test.cc) # Adds ASan unit tests and benchmarks for architecture. -macro(add_asan_tests_for_arch arch) +macro(add_asan_tests_for_arch_and_kind arch kind) # Instrumented tests. set(ASAN_INST_TEST_OBJECTS) foreach(src ${ASAN_INST_TEST_SOURCES}) - asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} - ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) + asan_compile(ASAN_INST_TEST_OBJECTS ${src} ${arch} ${kind} + ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN}) endforeach() if (APPLE) # Add Mac-specific helper. - asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} - ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC) + asan_compile(ASAN_INST_TEST_OBJECTS asan_mac_test_helpers.mm ${arch} ${kind} + ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -ObjC ${ARGN}) endif() - add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch} + add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test" ${arch} ${kind} OBJECTS ${ASAN_INST_TEST_OBJECTS} LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) + if(COMPILER_RT_BUILD_SHARED_ASAN) + add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Dynamic-Test" ${arch} ${kind} + OBJECTS ${ASAN_INST_TEST_OBJECTS} + LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS}) + endif() # Add static ASan runtime that will be linked with uninstrumented tests. - set(ASAN_TEST_RUNTIME RTAsanTest.${arch}) + set(ASAN_TEST_RUNTIME RTAsanTest.${arch}${kind}) if(APPLE) set(ASAN_TEST_RUNTIME_OBJECTS $<TARGET_OBJECTS:RTAsan.osx> @@ -187,10 +202,14 @@ macro(add_asan_tests_for_arch arch) else() set(ASAN_TEST_RUNTIME_OBJECTS $<TARGET_OBJECTS:RTAsan.${arch}> + $<TARGET_OBJECTS:RTAsan_cxx.${arch}> $<TARGET_OBJECTS:RTInterception.${arch}> - $<TARGET_OBJECTS:RTLSanCommon.${arch}> $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>) + if(NOT WIN32) + list(APPEND ASAN_TEST_RUNTIME_OBJECTS + $<TARGET_OBJECTS:RTLSanCommon.${arch}>) + endif() endif() add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS}) set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES @@ -198,10 +217,10 @@ macro(add_asan_tests_for_arch arch) # Uninstrumented tests. set(ASAN_NOINST_TEST_OBJECTS) foreach(src ${ASAN_NOINST_TEST_SOURCES}) - asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} - ${ASAN_UNITTEST_COMMON_CFLAGS}) + asan_compile(ASAN_NOINST_TEST_OBJECTS ${src} ${arch} ${kind} + ${ASAN_UNITTEST_COMMON_CFLAGS} ${ARGN}) endforeach() - add_asan_test(AsanUnitTests "Asan-${arch}-Noinst-Test" ${arch} + add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test" ${arch} ${kind} OBJECTS ${ASAN_NOINST_TEST_OBJECTS} LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS} WITH_TEST_RUNTIME) @@ -209,45 +228,53 @@ macro(add_asan_tests_for_arch arch) # Benchmarks. set(ASAN_BENCHMARKS_OBJECTS) foreach(src ${ASAN_BENCHMARKS_SOURCES}) - asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} - ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) + asan_compile(ASAN_BENCHMARKS_OBJECTS ${src} ${arch} ${kind} + ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${ARGN}) endforeach() - add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch} + add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark" ${arch} ${kind} OBJECTS ${ASAN_BENCHMARKS_OBJECTS} LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) + if(COMPILER_RT_BUILD_SHARED_ASAN) + add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Dynamic-Benchmark" ${arch} ${kind} + OBJECTS ${ASAN_BENCHMARKS_OBJECTS} + LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS}) + endif() endmacro() -if(COMPILER_RT_CAN_EXECUTE_TESTS) +if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID) foreach(arch ${ASAN_SUPPORTED_ARCH}) - add_asan_tests_for_arch(${arch}) + add_asan_tests_for_arch_and_kind(${arch} "-inline") + add_asan_tests_for_arch_and_kind(${arch} "-with-calls" + -mllvm -asan-instrumentation-with-call-threshold=0) endforeach() endif() if(ANDROID) - # We assume that unit tests on Android are built in a build - # tree with fresh Clang as a host compiler. - - # Test w/o ASan instrumentation. Link it with ASan statically. - add_executable(AsanNoinstTest - $<TARGET_OBJECTS:RTAsan.arm.android> - $<TARGET_OBJECTS:RTInterception.arm.android> - $<TARGET_OBJECTS:RTSanitizerCommon.arm.android> - ${COMPILER_RT_GTEST_SOURCE} - ${ASAN_NOINST_TEST_SOURCES}) - set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS}) - set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS}) - - # Test with ASan instrumentation. Link with ASan dynamic runtime. - add_executable(AsanTest - ${COMPILER_RT_GTEST_SOURCE} - ${ASAN_INST_TEST_SOURCES}) - set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) - set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) - target_link_libraries(AsanTest clang_rt.asan-arm-android) - - # Setup correct output directory and link flags. - set_target_properties(AsanNoinstTest AsanTest PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - # Add unit test to test suite. - add_dependencies(AsanUnitTests AsanNoinstTest AsanTest) + foreach(arch ${ASAN_SUPPORTED_ARCH}) + # Test w/o ASan instrumentation. Link it with ASan statically. + add_executable(AsanNoinstTest # FIXME: .arch? + $<TARGET_OBJECTS:RTAsan.${arch}> + $<TARGET_OBJECTS:RTInterception.${arch}> + $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> + $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> + ${COMPILER_RT_GTEST_SOURCE} + ${ASAN_NOINST_TEST_SOURCES}) + set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS}) + set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS}) + target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS}) + + # Test with ASan instrumentation. Link with ASan dynamic runtime. + add_executable(AsanTest + ${COMPILER_RT_GTEST_SOURCE} + ${ASAN_INST_TEST_SOURCES}) + set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}) + set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}) + target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS}) + + # Setup correct output directory and link flags. + set_target_properties(AsanNoinstTest AsanTest PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + # Add unit tests to the test suite. + add_dependencies(AsanUnitTests AsanNoinstTest AsanTest) + endforeach() endif() diff --git a/lib/asan/tests/asan_asm_test.cc b/lib/asan/tests/asan_asm_test.cc new file mode 100644 index 0000000000000..1d8b04d611bd5 --- /dev/null +++ b/lib/asan/tests/asan_asm_test.cc @@ -0,0 +1,267 @@ +//===-- asan_asm_test.cc --------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +//===----------------------------------------------------------------------===// +#include "asan_test_utils.h" + +#if defined(__linux__) + +#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__)) + +#include <emmintrin.h> + +namespace { + +template<typename T> void asm_write(T *ptr, T val); +template<typename T> T asm_read(T *ptr); +template<typename T> void asm_rep_movs(T *dst, T *src, size_t n); + +} // End of anonymous namespace + +#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__)) + +#if defined(__x86_64__) + +namespace { + +#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \ +template<> void asm_write<Type>(Type *ptr, Type val) { \ + __asm__( \ + Mov " %[val], (%[ptr]) \n\t" \ + : \ + : [ptr] "r" (ptr), [val] Reg (val) \ + : "memory" \ + ); \ +} + +#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \ +template<> Type asm_read<Type>(Type *ptr) { \ + Type res; \ + __asm__( \ + Mov " (%[ptr]), %[res] \n\t" \ + : [res] Reg (res) \ + : [ptr] "r" (ptr) \ + : "memory" \ + ); \ + return res; \ +} + +#define DECLARE_ASM_REP_MOVS(Type, Movs) \ + template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \ + __asm__("rep " Movs " \n\t" \ + : \ + : "D"(dst), "S"(src), "c"(size) \ + : "rsi", "rdi", "rcx", "memory"); \ + } + +DECLARE_ASM_WRITE(U8, "8", "movq", "r"); +DECLARE_ASM_READ(U8, "8", "movq", "=r"); +DECLARE_ASM_REP_MOVS(U8, "movsq"); + +} // End of anonymous namespace + +#endif // defined(__x86_64__) + +#if defined(__i386__) && defined(__SSE2__) + +namespace { + +#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \ +template<> void asm_write<Type>(Type *ptr, Type val) { \ + __asm__( \ + Mov " %[val], (%[ptr]) \n\t" \ + : \ + : [ptr] "r" (ptr), [val] Reg (val) \ + : "memory" \ + ); \ +} + +#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \ +template<> Type asm_read<Type>(Type *ptr) { \ + Type res; \ + __asm__( \ + Mov " (%[ptr]), %[res] \n\t" \ + : [res] Reg (res) \ + : [ptr] "r" (ptr) \ + : "memory" \ + ); \ + return res; \ +} + +#define DECLARE_ASM_REP_MOVS(Type, Movs) \ + template <> void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \ + __asm__("rep " Movs " \n\t" \ + : \ + : "D"(dst), "S"(src), "c"(size) \ + : "esi", "edi", "ecx", "memory"); \ + } + +} // End of anonymous namespace + +#endif // defined(__i386__) && defined(__SSE2__) + +#if defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__)) + +namespace { + +DECLARE_ASM_WRITE(U1, "1", "movb", "r"); +DECLARE_ASM_WRITE(U2, "2", "movw", "r"); +DECLARE_ASM_WRITE(U4, "4", "movl", "r"); +DECLARE_ASM_WRITE(__m128i, "16", "movaps", "x"); + +DECLARE_ASM_READ(U1, "1", "movb", "=r"); +DECLARE_ASM_READ(U2, "2", "movw", "=r"); +DECLARE_ASM_READ(U4, "4", "movl", "=r"); +DECLARE_ASM_READ(__m128i, "16", "movaps", "=x"); + +DECLARE_ASM_REP_MOVS(U1, "movsb"); +DECLARE_ASM_REP_MOVS(U2, "movsw"); +DECLARE_ASM_REP_MOVS(U4, "movsl"); + +template<typename T> void TestAsmWrite(const char *DeathPattern) { + T *buf = new T; + EXPECT_DEATH(asm_write(&buf[1], static_cast<T>(0)), DeathPattern); + T var = 0x12; + asm_write(&var, static_cast<T>(0x21)); + ASSERT_EQ(static_cast<T>(0x21), var); + delete buf; +} + +template<> void TestAsmWrite<__m128i>(const char *DeathPattern) { + char *buf = new char[16]; + char *p = buf + 16; + if (((uintptr_t) p % 16) != 0) + p = buf + 8; + assert(((uintptr_t) p % 16) == 0); + __m128i val = _mm_set1_epi16(0x1234); + EXPECT_DEATH(asm_write<__m128i>((__m128i*) p, val), DeathPattern); + __m128i var = _mm_set1_epi16(0x4321); + asm_write(&var, val); + ASSERT_EQ(0x1234, _mm_extract_epi16(var, 0)); + delete [] buf; +} + +template<typename T> void TestAsmRead(const char *DeathPattern) { + T *buf = new T; + EXPECT_DEATH(asm_read(&buf[1]), DeathPattern); + T var = 0x12; + ASSERT_EQ(static_cast<T>(0x12), asm_read(&var)); + delete buf; +} + +template<> void TestAsmRead<__m128i>(const char *DeathPattern) { + char *buf = new char[16]; + char *p = buf + 16; + if (((uintptr_t) p % 16) != 0) + p = buf + 8; + assert(((uintptr_t) p % 16) == 0); + EXPECT_DEATH(asm_read<__m128i>((__m128i*) p), DeathPattern); + __m128i val = _mm_set1_epi16(0x1234); + ASSERT_EQ(0x1234, _mm_extract_epi16(asm_read(&val), 0)); + delete [] buf; +} + +U4 AsmLoad(U4 *a) { + U4 r; + __asm__("movl (%[a]), %[r] \n\t" : [r] "=r" (r) : [a] "r" (a) : "memory"); + return r; +} + +void AsmStore(U4 r, U4 *a) { + __asm__("movl %[r], (%[a]) \n\t" : : [a] "r" (a), [r] "r" (r) : "memory"); +} + +template <typename T> +void TestAsmRepMovs(const char *DeathPatternRead, + const char *DeathPatternWrite) { + T src_good[4] = { 0x0, 0x1, 0x2, 0x3 }; + T dst_good[4] = {}; + asm_rep_movs(dst_good, src_good, 4); + ASSERT_EQ(static_cast<T>(0x0), dst_good[0]); + ASSERT_EQ(static_cast<T>(0x1), dst_good[1]); + ASSERT_EQ(static_cast<T>(0x2), dst_good[2]); + ASSERT_EQ(static_cast<T>(0x3), dst_good[3]); + + T dst_bad[3]; + EXPECT_DEATH(asm_rep_movs(dst_bad, src_good, 4), DeathPatternWrite); + + T src_bad[3] = { 0x0, 0x1, 0x2 }; + EXPECT_DEATH(asm_rep_movs(dst_good, src_bad, 4), DeathPatternRead); + + T* dp = dst_bad + 4; + T* sp = src_bad + 4; + asm_rep_movs(dp, sp, 0); +} + +} // End of anonymous namespace + +TEST(AddressSanitizer, asm_load_store) { + U4* buf = new U4[2]; + EXPECT_DEATH(AsmLoad(&buf[3]), "READ of size 4"); + EXPECT_DEATH(AsmStore(0x1234, &buf[3]), "WRITE of size 4"); + delete [] buf; +} + +TEST(AddressSanitizer, asm_rw) { + TestAsmWrite<U1>("WRITE of size 1"); + TestAsmWrite<U2>("WRITE of size 2"); + TestAsmWrite<U4>("WRITE of size 4"); +#if defined(__x86_64__) + TestAsmWrite<U8>("WRITE of size 8"); +#endif // defined(__x86_64__) + TestAsmWrite<__m128i>("WRITE of size 16"); + + TestAsmRead<U1>("READ of size 1"); + TestAsmRead<U2>("READ of size 2"); + TestAsmRead<U4>("READ of size 4"); +#if defined(__x86_64__) + TestAsmRead<U8>("READ of size 8"); +#endif // defined(__x86_64__) + TestAsmRead<__m128i>("READ of size 16"); +} + +TEST(AddressSanitizer, asm_flags) { + long magic = 0x1234; + long r = 0x0; + +#if defined(__x86_64__) + __asm__("xorq %%rax, %%rax \n\t" + "movq (%[p]), %%rax \n\t" + "sete %%al \n\t" + "movzbq %%al, %[r] \n\t" + : [r] "=r"(r) + : [p] "r"(&magic) + : "rax", "memory"); +#else + __asm__("xorl %%eax, %%eax \n\t" + "movl (%[p]), %%eax \n\t" + "sete %%al \n\t" + "movzbl %%al, %[r] \n\t" + : [r] "=r"(r) + : [p] "r"(&magic) + : "eax", "memory"); +#endif // defined(__x86_64__) + + ASSERT_EQ(0x1, r); +} + +TEST(AddressSanitizer, asm_rep_movs) { + TestAsmRepMovs<U1>("READ of size 1", "WRITE of size 1"); + TestAsmRepMovs<U2>("READ of size 2", "WRITE of size 2"); + TestAsmRepMovs<U4>("READ of size 4", "WRITE of size 4"); +#if defined(__x86_64__) + TestAsmRepMovs<U8>("READ of size 8", "WRITE of size 8"); +#endif // defined(__x86_64__) +} + +#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__)) + +#endif // defined(__linux__) diff --git a/lib/asan/tests/asan_fake_stack_test.cc b/lib/asan/tests/asan_fake_stack_test.cc index 1c98125eb45e6..516142f0c3b73 100644 --- a/lib/asan/tests/asan_fake_stack_test.cc +++ b/lib/asan/tests/asan_fake_stack_test.cc @@ -59,14 +59,16 @@ TEST(FakeStack, FlagsOffset) { } } +#if !defined(_WIN32) // FIXME: Fails due to OOM on Windows. TEST(FakeStack, CreateDestroy) { for (int i = 0; i < 1000; i++) { for (uptr stack_size_log = 20; stack_size_log <= 22; stack_size_log++) { FakeStack *fake_stack = FakeStack::Create(stack_size_log); - fake_stack->Destroy(); + fake_stack->Destroy(0); } } } +#endif TEST(FakeStack, ModuloNumberOfFrames) { EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, 0), 0U); @@ -98,7 +100,7 @@ TEST(FakeStack, GetFrame) { EXPECT_EQ(base + 0*stack_size + 64 * 7, fs->GetFrame(stack_size_log, 0, 7U)); EXPECT_EQ(base + 1*stack_size + 128 * 3, fs->GetFrame(stack_size_log, 1, 3U)); EXPECT_EQ(base + 2*stack_size + 256 * 5, fs->GetFrame(stack_size_log, 2, 5U)); - fs->Destroy(); + fs->Destroy(0); } TEST(FakeStack, Allocate) { @@ -127,7 +129,7 @@ TEST(FakeStack, Allocate) { fs->Deallocate(reinterpret_cast<uptr>(it->first), it->second); } } - fs->Destroy(); + fs->Destroy(0); } static void RecursiveFunction(FakeStack *fs, int depth) { @@ -144,7 +146,7 @@ TEST(FakeStack, RecursiveStressTest) { const uptr stack_size_log = 16; FakeStack *fs = FakeStack::Create(stack_size_log); RecursiveFunction(fs, 22); // with 26 runs for 2-3 seconds. - fs->Destroy(); + fs->Destroy(0); } } // namespace __asan diff --git a/lib/asan/tests/asan_interface_test.cc b/lib/asan/tests/asan_interface_test.cc index f36679012f278..50fdf1119f0ba 100644 --- a/lib/asan/tests/asan_interface_test.cc +++ b/lib/asan/tests/asan_interface_test.cc @@ -11,18 +11,19 @@ // //===----------------------------------------------------------------------===// #include "asan_test_utils.h" -#include "sanitizer/asan_interface.h" +#include <sanitizer/allocator_interface.h> +#include <sanitizer/asan_interface.h> TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) { - EXPECT_EQ(0U, __asan_get_estimated_allocated_size(0)); + EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0)); const size_t sizes[] = { 1, 30, 1<<30 }; for (size_t i = 0; i < 3; i++) { - EXPECT_EQ(sizes[i], __asan_get_estimated_allocated_size(sizes[i])); + EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i])); } } static const char* kGetAllocatedSizeErrorMsg = - "attempting to call __asan_get_allocated_size()"; + "attempting to call __sanitizer_get_allocated_size"; TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) { const size_t kArraySize = 100; @@ -31,38 +32,41 @@ TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) { // Allocated memory is owned by allocator. Allocated size should be // equal to requested size. - EXPECT_EQ(true, __asan_get_ownership(array)); - EXPECT_EQ(kArraySize, __asan_get_allocated_size(array)); - EXPECT_EQ(true, __asan_get_ownership(int_ptr)); - EXPECT_EQ(sizeof(int), __asan_get_allocated_size(int_ptr)); + EXPECT_EQ(true, __sanitizer_get_ownership(array)); + EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array)); + EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr)); + EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr)); // We cannot call GetAllocatedSize from the memory we didn't map, // and from the interior pointers (not returned by previous malloc). void *wild_addr = (void*)0x1; - EXPECT_FALSE(__asan_get_ownership(wild_addr)); - EXPECT_DEATH(__asan_get_allocated_size(wild_addr), kGetAllocatedSizeErrorMsg); - EXPECT_FALSE(__asan_get_ownership(array + kArraySize / 2)); - EXPECT_DEATH(__asan_get_allocated_size(array + kArraySize / 2), + EXPECT_FALSE(__sanitizer_get_ownership(wild_addr)); + EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr), + kGetAllocatedSizeErrorMsg); + EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2)); + EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2), kGetAllocatedSizeErrorMsg); - // NULL is not owned, but is a valid argument for __asan_get_allocated_size(). - EXPECT_FALSE(__asan_get_ownership(NULL)); - EXPECT_EQ(0U, __asan_get_allocated_size(NULL)); + // NULL is not owned, but is a valid argument for + // __sanitizer_get_allocated_size(). + EXPECT_FALSE(__sanitizer_get_ownership(NULL)); + EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL)); // When memory is freed, it's not owned, and call to GetAllocatedSize // is forbidden. free(array); - EXPECT_FALSE(__asan_get_ownership(array)); - EXPECT_DEATH(__asan_get_allocated_size(array), kGetAllocatedSizeErrorMsg); + EXPECT_FALSE(__sanitizer_get_ownership(array)); + EXPECT_DEATH(__sanitizer_get_allocated_size(array), + kGetAllocatedSizeErrorMsg); delete int_ptr; void *zero_alloc = Ident(malloc(0)); if (zero_alloc != 0) { // If malloc(0) is not null, this pointer is owned and should have valid // allocated size. - EXPECT_TRUE(__asan_get_ownership(zero_alloc)); + EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc)); // Allocated size is 0 or 1 depending on the allocator used. - EXPECT_LT(__asan_get_allocated_size(zero_alloc), 2U); + EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U); } free(zero_alloc); } @@ -71,14 +75,14 @@ TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) { size_t before_malloc, after_malloc, after_free; char *array; const size_t kMallocSize = 100; - before_malloc = __asan_get_current_allocated_bytes(); + before_malloc = __sanitizer_get_current_allocated_bytes(); array = Ident((char*)malloc(kMallocSize)); - after_malloc = __asan_get_current_allocated_bytes(); + after_malloc = __sanitizer_get_current_allocated_bytes(); EXPECT_EQ(before_malloc + kMallocSize, after_malloc); free(array); - after_free = __asan_get_current_allocated_bytes(); + after_free = __sanitizer_get_current_allocated_bytes(); EXPECT_EQ(before_malloc, after_free); } @@ -88,11 +92,11 @@ TEST(AddressSanitizerInterface, GetHeapSizeTest) { // otherwise it will be stuck in quarantine instead of being unmaped. static const size_t kLargeMallocSize = (1 << 28) + 1; // 256M free(Ident(malloc(kLargeMallocSize))); // Drain quarantine. - size_t old_heap_size = __asan_get_heap_size(); + size_t old_heap_size = __sanitizer_get_heap_size(); for (int i = 0; i < 3; i++) { // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize); free(Ident(malloc(kLargeMallocSize))); - EXPECT_EQ(old_heap_size, __asan_get_heap_size()); + EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size()); } } @@ -116,7 +120,7 @@ static void *ManyThreadsWithStatsWorker(void *arg) { TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) { size_t before_test, after_test, i; pthread_t threads[kManyThreadsNumThreads]; - before_test = __asan_get_current_allocated_bytes(); + before_test = __sanitizer_get_current_allocated_bytes(); for (i = 0; i < kManyThreadsNumThreads; i++) { PTHREAD_CREATE(&threads[i], 0, (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i); @@ -124,7 +128,7 @@ TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) { for (i = 0; i < kManyThreadsNumThreads; i++) { PTHREAD_JOIN(threads[i], 0); } - after_test = __asan_get_current_allocated_bytes(); + after_test = __sanitizer_get_current_allocated_bytes(); // ASan stats also reflect memory usage of internal ASan RTL structs, // so we can't check for equality here. EXPECT_LT(after_test, before_test + (1UL<<20)); @@ -148,6 +152,7 @@ TEST(AddressSanitizerInterface, ExitCode) { static void MyDeathCallback() { fprintf(stderr, "MyDeathCallback\n"); + fflush(0); // On Windows, stderr doesn't flush on crash. } TEST(AddressSanitizerInterface, DeathCallbackTest) { @@ -389,6 +394,7 @@ TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) { free(array); } +#if !defined(_WIN32) // FIXME: This should really be a lit test. static void ErrorReportCallbackOneToZ(const char *report) { int report_len = strlen(report); ASSERT_EQ(6, write(2, "ABCDEF", 6)); @@ -403,6 +409,7 @@ TEST(AddressSanitizerInterface, SetErrorReportCallbackTest) { ASAN_PCRE_DOTALL "ABCDEF.*AddressSanitizer.*WRITE.*ABCDEF"); __asan_set_error_report_callback(NULL); } +#endif TEST(AddressSanitizerInterface, GetOwnershipStressTest) { std::vector<char *> pointers; @@ -414,11 +421,11 @@ TEST(AddressSanitizerInterface, GetOwnershipStressTest) { sizes.push_back(size); } for (size_t i = 0; i < 4000000; i++) { - EXPECT_FALSE(__asan_get_ownership(&pointers)); - EXPECT_FALSE(__asan_get_ownership((void*)0x1234)); + EXPECT_FALSE(__sanitizer_get_ownership(&pointers)); + EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234)); size_t idx = i % kNumMallocs; - EXPECT_TRUE(__asan_get_ownership(pointers[idx])); - EXPECT_EQ(sizes[idx], __asan_get_allocated_size(pointers[idx])); + EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx])); + EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx])); } for (size_t i = 0, n = pointers.size(); i < n; i++) free(pointers[i]); diff --git a/lib/asan/tests/asan_mem_test.cc b/lib/asan/tests/asan_mem_test.cc index 60f5cd4cf7609..4a941faa0430f 100644 --- a/lib/asan/tests/asan_mem_test.cc +++ b/lib/asan/tests/asan_mem_test.cc @@ -76,17 +76,17 @@ TEST(AddressSanitizer, MemSetOOBTest) { // Strictly speaking we are not guaranteed to find such two pointers, // but given the structure of asan's allocator we will. static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) { - vector<char *> v; + vector<uintptr_t> v; bool res = false; for (size_t i = 0; i < 1000U && !res; i++) { - v.push_back(new char[size]); + v.push_back(reinterpret_cast<uintptr_t>(new char[size])); if (i == 0) continue; sort(v.begin(), v.end()); for (size_t j = 1; j < v.size(); j++) { assert(v[j] > v[j-1]); if ((size_t)(v[j] - v[j-1]) < size * 2) { - *x2 = v[j]; - *x1 = v[j-1]; + *x2 = reinterpret_cast<char*>(v[j]); + *x1 = reinterpret_cast<char*>(v[j-1]); res = true; break; } @@ -94,9 +94,10 @@ static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) { } for (size_t i = 0; i < v.size(); i++) { - if (res && v[i] == *x1) continue; - if (res && v[i] == *x2) continue; - delete [] v[i]; + char *p = reinterpret_cast<char *>(v[i]); + if (res && p == *x1) continue; + if (res && p == *x2) continue; + delete [] p; } return res; } diff --git a/lib/asan/tests/asan_noinst_test.cc b/lib/asan/tests/asan_noinst_test.cc index cb6223c09a469..bb6af45bddf90 100644 --- a/lib/asan/tests/asan_noinst_test.cc +++ b/lib/asan/tests/asan_noinst_test.cc @@ -16,6 +16,7 @@ #include "asan_internal.h" #include "asan_mapping.h" #include "asan_test_utils.h" +#include <sanitizer/allocator_interface.h> #include <assert.h> #include <stdio.h> @@ -25,40 +26,19 @@ #include <vector> #include <limits> -#if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1 -// Manually set correct ASan mapping scale and offset, as they won't be -// exported from instrumented sources (there are none). -# define FLEXIBLE_SHADOW_SCALE kDefaultShadowScale -# if SANITIZER_ANDROID -# define FLEXIBLE_SHADOW_OFFSET (0) -# else -# if SANITIZER_WORDSIZE == 32 -# if defined(__mips__) -# define FLEXIBLE_SHADOW_OFFSET kMIPS32_ShadowOffset32 -# else -# define FLEXIBLE_SHADOW_OFFSET kDefaultShadowOffset32 -# endif -# else -# if defined(__powerpc64__) -# define FLEXIBLE_SHADOW_OFFSET kPPC64_ShadowOffset64 -# elif SANITIZER_MAC -# define FLEXIBLE_SHADOW_OFFSET kDefaultShadowOffset64 -# else -# define FLEXIBLE_SHADOW_OFFSET kDefaultShort64bitShadowOffset -# endif -# endif -# endif -SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale = FLEXIBLE_SHADOW_SCALE; -SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset = - FLEXIBLE_SHADOW_OFFSET; -#endif // ASAN_FLEXIBLE_MAPPING_AND_OFFSET +// ATTENTION! +// Please don't call intercepted functions (including malloc() and friends) +// in this test. The static runtime library is linked explicitly (without +// -fsanitize=address), thus the interceptors do not work correctly on OS X. +#if !defined(_WIN32) extern "C" { // Set specific ASan options for uninstrumented unittest. const char* __asan_default_options() { return "allow_reexec=0"; } } // extern "C" +#endif // Make sure __asan_init is called before any test case is run. struct AsanInitCaller { @@ -72,19 +52,19 @@ TEST(AddressSanitizer, InternalSimpleDeathTest) { static void MallocStress(size_t n) { u32 seed = my_rand(); - StackTrace stack1; - stack1.trace[0] = 0xa123; - stack1.trace[1] = 0xa456; + BufferedStackTrace stack1; + stack1.trace_buffer[0] = 0xa123; + stack1.trace_buffer[1] = 0xa456; stack1.size = 2; - StackTrace stack2; - stack2.trace[0] = 0xb123; - stack2.trace[1] = 0xb456; + BufferedStackTrace stack2; + stack2.trace_buffer[0] = 0xb123; + stack2.trace_buffer[1] = 0xb456; stack2.size = 2; - StackTrace stack3; - stack3.trace[0] = 0xc123; - stack3.trace[1] = 0xc456; + BufferedStackTrace stack3; + stack3.trace_buffer[0] = 0xc123; + stack3.trace_buffer[1] = 0xc456; stack3.size = 2; std::vector<void *> vec; @@ -160,8 +140,8 @@ TEST(AddressSanitizer, DISABLED_InternalPrintShadow) { } TEST(AddressSanitizer, QuarantineTest) { - StackTrace stack; - stack.trace[0] = 0x890; + BufferedStackTrace stack; + stack.trace_buffer[0] = 0x890; stack.size = 1; const int size = 1024; @@ -181,8 +161,8 @@ TEST(AddressSanitizer, QuarantineTest) { void *ThreadedQuarantineTestWorker(void *unused) { (void)unused; u32 seed = my_rand(); - StackTrace stack; - stack.trace[0] = 0x890; + BufferedStackTrace stack; + stack.trace_buffer[0] = 0x890; stack.size = 1; for (size_t i = 0; i < 1000; i++) { @@ -196,20 +176,20 @@ void *ThreadedQuarantineTestWorker(void *unused) { // destroyed. TEST(AddressSanitizer, ThreadedQuarantineTest) { const int n_threads = 3000; - size_t mmaped1 = __asan_get_heap_size(); + size_t mmaped1 = __sanitizer_get_heap_size(); for (int i = 0; i < n_threads; i++) { pthread_t t; PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0); PTHREAD_JOIN(t, 0); - size_t mmaped2 = __asan_get_heap_size(); + size_t mmaped2 = __sanitizer_get_heap_size(); EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20)); } } void *ThreadedOneSizeMallocStress(void *unused) { (void)unused; - StackTrace stack; - stack.trace[0] = 0x890; + BufferedStackTrace stack; + stack.trace_buffer[0] = 0x890; stack.size = 1; const size_t kNumMallocs = 1000; for (int iter = 0; iter < 1000; iter++) { @@ -245,3 +225,45 @@ TEST(AddressSanitizer, ShadowRegionIsPoisonedTest) { ptr = kHighShadowBeg + 200; EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100)); } + +// Test __asan_load1 & friends. +TEST(AddressSanitizer, LoadStoreCallbacks) { + typedef void (*CB)(uptr p); + CB cb[2][5] = { + { + __asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16, + }, { + __asan_store1, __asan_store2, __asan_store4, __asan_store8, + __asan_store16, + } + }; + + uptr buggy_ptr; + + __asan_test_only_reported_buggy_pointer = &buggy_ptr; + BufferedStackTrace stack; + stack.trace_buffer[0] = 0x890; + stack.size = 1; + + for (uptr len = 16; len <= 32; len++) { + char *ptr = (char*) __asan::asan_malloc(len, &stack); + uptr p = reinterpret_cast<uptr>(ptr); + for (uptr is_write = 0; is_write <= 1; is_write++) { + for (uptr size_log = 0; size_log <= 4; size_log++) { + uptr size = 1 << size_log; + CB call = cb[is_write][size_log]; + // Iterate only size-aligned offsets. + for (uptr offset = 0; offset <= len; offset += size) { + buggy_ptr = 0; + call(p + offset); + if (offset + size <= len) + EXPECT_EQ(buggy_ptr, 0U); + else + EXPECT_EQ(buggy_ptr, p + offset); + } + } + } + __asan::asan_free(ptr, &stack, __asan::FROM_MALLOC); + } + __asan_test_only_reported_buggy_pointer = 0; +} diff --git a/lib/asan/tests/asan_oob_test.cc b/lib/asan/tests/asan_oob_test.cc index f8343f19cfcb0..0c6bea2858649 100644 --- a/lib/asan/tests/asan_oob_test.cc +++ b/lib/asan/tests/asan_oob_test.cc @@ -75,7 +75,9 @@ TEST(AddressSanitizer, OOB_int) { } TEST(AddressSanitizer, OOBRightTest) { - for (size_t access_size = 1; access_size <= 8; access_size *= 2) { + size_t max_access_size = SANITIZER_WORDSIZE == 64 ? 8 : 4; + for (size_t access_size = 1; access_size <= max_access_size; + access_size *= 2) { for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) { for (size_t offset = 0; offset <= 8; offset += access_size) { void *p = malloc(alloc_size); diff --git a/lib/asan/tests/asan_racy_double_free_test.cc b/lib/asan/tests/asan_racy_double_free_test.cc index deeeb4f45e2fb..23240e714d561 100644 --- a/lib/asan/tests/asan_racy_double_free_test.cc +++ b/lib/asan/tests/asan_racy_double_free_test.cc @@ -7,7 +7,7 @@ void *x[N]; void *Thread1(void *unused) { for (int i = 0; i < N; i++) { - fprintf(stderr, "%s %d\n", __FUNCTION__, i); + fprintf(stderr, "%s %d\n", __func__, i); free(x[i]); } return NULL; @@ -15,7 +15,7 @@ void *Thread1(void *unused) { void *Thread2(void *unused) { for (int i = 0; i < N; i++) { - fprintf(stderr, "%s %d\n", __FUNCTION__, i); + fprintf(stderr, "%s %d\n", __func__, i); free(x[i]); } return NULL; diff --git a/lib/asan/tests/asan_str_test.cc b/lib/asan/tests/asan_str_test.cc index 178d00d4da862..1cd2a08b90213 100644 --- a/lib/asan/tests/asan_str_test.cc +++ b/lib/asan/tests/asan_str_test.cc @@ -77,7 +77,7 @@ TEST(AddressSanitizer, WcsLenTest) { free(heap_string); } -#ifndef __APPLE__ +#if SANITIZER_TEST_HAS_STRNLEN TEST(AddressSanitizer, StrNLenOOBTest) { size_t size = Ident(123); char *str = MallocAndMemsetString(size); @@ -95,7 +95,7 @@ TEST(AddressSanitizer, StrNLenOOBTest) { EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0)); free(str); } -#endif +#endif // SANITIZER_TEST_HAS_STRNLEN TEST(AddressSanitizer, StrDupOOBTest) { size_t size = Ident(42); @@ -186,7 +186,7 @@ TEST(AddressSanitizer, StrNCpyOOBTest) { typedef char*(*PointerToStrChr1)(const char*, int); typedef char*(*PointerToStrChr2)(char*, int); -USED static void RunStrChrTest(PointerToStrChr1 StrChr) { +UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) { size_t size = Ident(100); char *str = MallocAndMemsetString(size); str[10] = 'q'; @@ -202,7 +202,7 @@ USED static void RunStrChrTest(PointerToStrChr1 StrChr) { EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0)); free(str); } -USED static void RunStrChrTest(PointerToStrChr2 StrChr) { +UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) { size_t size = Ident(100); char *str = MallocAndMemsetString(size); str[10] = 'q'; @@ -221,7 +221,10 @@ USED static void RunStrChrTest(PointerToStrChr2 StrChr) { TEST(AddressSanitizer, StrChrAndIndexOOBTest) { RunStrChrTest(&strchr); +// No index() on Windows and on Android L. +#if !defined(_WIN32) && !defined(__ANDROID__) RunStrChrTest(&index); +#endif } TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) { @@ -244,6 +247,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) { EXPECT_LT(0, strncmp("baa", "aaa", 1)); EXPECT_LT(0, strncmp("zyx", "", 2)); +#if !defined(_WIN32) // no str[n]casecmp on Windows. // strcasecmp EXPECT_EQ(0, strcasecmp("", "")); EXPECT_EQ(0, strcasecmp("zzz", "zzz")); @@ -263,6 +267,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) { EXPECT_LT(0, strncasecmp("xyz", "xyy", 10)); EXPECT_LT(0, strncasecmp("Baa", "aaa", 1)); EXPECT_LT(0, strncasecmp("zyx", "", 2)); +#endif // memcmp EXPECT_EQ(0, memcmp("a", "b", 0)); @@ -305,9 +310,11 @@ TEST(AddressSanitizer, StrCmpOOBTest) { RunStrCmpTest(&strcmp); } +#if !defined(_WIN32) // no str[n]casecmp on Windows. TEST(AddressSanitizer, StrCaseCmpOOBTest) { RunStrCmpTest(&strcasecmp); } +#endif typedef int(*PointerToStrNCmp)(const char*, const char*, size_t); void RunStrNCmpTest(PointerToStrNCmp StrNCmp) { @@ -340,9 +347,12 @@ TEST(AddressSanitizer, StrNCmpOOBTest) { RunStrNCmpTest(&strncmp); } +#if !defined(_WIN32) // no str[n]casecmp on Windows. TEST(AddressSanitizer, StrNCaseCmpOOBTest) { RunStrNCmpTest(&strncasecmp); } +#endif + TEST(AddressSanitizer, StrCatOOBTest) { // strcat() reads strlen(to) bytes from |to| before concatenating. size_t to_size = Ident(100); @@ -489,15 +499,6 @@ TEST(AddressSanitizer, StrArgsOverlapTest) { free(str); } -void CallAtoi(const char *nptr) { - Ident(atoi(nptr)); -} -void CallAtol(const char *nptr) { - Ident(atol(nptr)); -} -void CallAtoll(const char *nptr) { - Ident(atoll(nptr)); -} typedef void(*PointerToCallAtoi)(const char*); void RunAtoiOOBTest(PointerToCallAtoi Atoi) { @@ -524,18 +525,23 @@ void RunAtoiOOBTest(PointerToCallAtoi Atoi) { free(array); } +#if !defined(_WIN32) // FIXME: Fix and enable on Windows. +void CallAtoi(const char *nptr) { + Ident(atoi(nptr)); +} +void CallAtol(const char *nptr) { + Ident(atol(nptr)); +} +void CallAtoll(const char *nptr) { + Ident(atoll(nptr)); +} TEST(AddressSanitizer, AtoiAndFriendsOOBTest) { RunAtoiOOBTest(&CallAtoi); RunAtoiOOBTest(&CallAtol); RunAtoiOOBTest(&CallAtoll); } +#endif -void CallStrtol(const char *nptr, char **endptr, int base) { - Ident(strtol(nptr, endptr, base)); -} -void CallStrtoll(const char *nptr, char **endptr, int base) { - Ident(strtoll(nptr, endptr, base)); -} typedef void(*PointerToCallStrtol)(const char*, char**, int); void RunStrtolOOBTest(PointerToCallStrtol Strtol) { @@ -578,11 +584,19 @@ void RunStrtolOOBTest(PointerToCallStrtol Strtol) { free(array); } +#if !defined(_WIN32) // FIXME: Fix and enable on Windows. +void CallStrtol(const char *nptr, char **endptr, int base) { + Ident(strtol(nptr, endptr, base)); +} +void CallStrtoll(const char *nptr, char **endptr, int base) { + Ident(strtoll(nptr, endptr, base)); +} TEST(AddressSanitizer, StrtollOOBTest) { RunStrtolOOBTest(&CallStrtoll); } TEST(AddressSanitizer, StrtolOOBTest) { RunStrtolOOBTest(&CallStrtol); } +#endif diff --git a/lib/asan/tests/asan_test.cc b/lib/asan/tests/asan_test.cc index 6539ae8af4ead..67bcbaca1e40b 100644 --- a/lib/asan/tests/asan_test.cc +++ b/lib/asan/tests/asan_test.cc @@ -25,27 +25,10 @@ NOINLINE void *malloc_bbb(size_t size) { NOINLINE void *malloc_aaa(size_t size) { void *res = malloc_bbb(size); break_optimization(0); return res;} -#ifndef __APPLE__ -NOINLINE void *memalign_fff(size_t alignment, size_t size) { - void *res = memalign/**/(alignment, size); break_optimization(0); return res;} -NOINLINE void *memalign_eee(size_t alignment, size_t size) { - void *res = memalign_fff(alignment, size); break_optimization(0); return res;} -NOINLINE void *memalign_ddd(size_t alignment, size_t size) { - void *res = memalign_eee(alignment, size); break_optimization(0); return res;} -NOINLINE void *memalign_ccc(size_t alignment, size_t size) { - void *res = memalign_ddd(alignment, size); break_optimization(0); return res;} -NOINLINE void *memalign_bbb(size_t alignment, size_t size) { - void *res = memalign_ccc(alignment, size); break_optimization(0); return res;} -NOINLINE void *memalign_aaa(size_t alignment, size_t size) { - void *res = memalign_bbb(alignment, size); break_optimization(0); return res;} -#endif // __APPLE__ - - NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);} NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);} NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);} - template<typename T> NOINLINE void uaf_test(int size, int off) { char *p = (char *)malloc_aaa(size); @@ -90,19 +73,19 @@ TEST(AddressSanitizer, VariousMallocsTest) { *c = 0; delete c; -#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__) +#if SANITIZER_TEST_HAS_POSIX_MEMALIGN int *pm; int pm_res = posix_memalign((void**)&pm, kPageSize, kPageSize); EXPECT_EQ(0, pm_res); free(pm); -#endif +#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN -#if !defined(__APPLE__) +#if SANITIZER_TEST_HAS_MEMALIGN int *ma = (int*)memalign(kPageSize, kPageSize); EXPECT_EQ(0U, (uintptr_t)ma % kPageSize); ma[123] = 0; free(ma); -#endif // __APPLE__ +#endif // SANITIZER_TEST_HAS_MEMALIGN } TEST(AddressSanitizer, CallocTest) { @@ -124,18 +107,25 @@ TEST(AddressSanitizer, CallocReturnsZeroMem) { EXPECT_EQ(x[size / 4], 0); memset(x, 0x42, size); free(Ident(x)); +#if !defined(_WIN32) + // FIXME: OOM on Windows. We should just make this a lit test + // with quarantine size set to 1. free(Ident(malloc(Ident(1 << 27)))); // Try to drain the quarantine. +#endif } } } +// No valloc on Windows or Android. +#if !defined(_WIN32) && !defined(__ANDROID__) TEST(AddressSanitizer, VallocTest) { void *a = valloc(100); EXPECT_EQ(0U, (uintptr_t)a % kPageSize); free(a); } +#endif -#ifndef __APPLE__ +#if SANITIZER_TEST_HAS_PVALLOC TEST(AddressSanitizer, PvallocTest) { char *a = (char*)pvalloc(kPageSize + 100); EXPECT_EQ(0U, (uintptr_t)a % kPageSize); @@ -147,8 +137,10 @@ TEST(AddressSanitizer, PvallocTest) { a[101] = 1; // we should not report an error here. free(a); } -#endif // __APPLE__ +#endif // SANITIZER_TEST_HAS_PVALLOC +#if !defined(_WIN32) +// FIXME: Use an equivalent of pthread_setspecific on Windows. void *TSDWorker(void *test_key) { if (test_key) { pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface); @@ -178,6 +170,7 @@ TEST(AddressSanitizer, DISABLED_TSDTest) { PTHREAD_JOIN(th, NULL); pthread_key_delete(test_key); } +#endif TEST(AddressSanitizer, UAF_char) { const char *uaf_string = "AddressSanitizer:.*heap-use-after-free"; @@ -191,18 +184,27 @@ TEST(AddressSanitizer, UAF_char) { TEST(AddressSanitizer, UAF_long_double) { if (sizeof(long double) == sizeof(double)) return; long double *p = Ident(new long double[10]); - EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[06]"); - EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[06]"); + EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[026]"); + EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[026]"); delete [] Ident(p); } +#if !defined(_WIN32) struct Packed5 { int x; char c; } __attribute__((packed)); - +#else +# pragma pack(push, 1) +struct Packed5 { + int x; + char c; +}; +# pragma pack(pop) +#endif TEST(AddressSanitizer, UAF_Packed5) { + static_assert(sizeof(Packed5) == 5, "Please check the keywords used"); Packed5 *p = Ident(new Packed5[2]); EXPECT_DEATH(p[0] = p[3], "READ of size 5"); EXPECT_DEATH(p[3] = p[0], "WRITE of size 5"); @@ -299,12 +301,14 @@ TEST(AddressSanitizer, LargeMallocTest) { } TEST(AddressSanitizer, HugeMallocTest) { - if (SANITIZER_WORDSIZE != 64) return; + if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return; size_t n_megs = 4100; - TestLargeMalloc(n_megs << 20); + EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0, + "is located 1 bytes to the left|" + "AddressSanitizer failed to allocate"); } -#ifndef __APPLE__ +#if SANITIZER_TEST_HAS_MEMALIGN void MemalignRun(size_t align, size_t size, int idx) { char *p = (char *)memalign(align, size); Ident(p)[idx] = 0; @@ -320,7 +324,7 @@ TEST(AddressSanitizer, memalign) { "is located 1 bytes to the right"); } } -#endif +#endif // SANITIZER_TEST_HAS_MEMALIGN void *ManyThreadsWorker(void *a) { for (int iter = 0; iter < 100; iter++) { @@ -379,12 +383,12 @@ TEST(AddressSanitizer, ZeroSizeMallocTest) { void *ptr = Ident(malloc(0)); EXPECT_TRUE(NULL != ptr); free(ptr); -#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__) +#if SANITIZER_TEST_HAS_POSIX_MEMALIGN int pm_res = posix_memalign(&ptr, 1<<20, 0); EXPECT_EQ(0, pm_res); EXPECT_TRUE(NULL != ptr); free(ptr); -#endif +#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN int *int_ptr = new int[0]; int *int_ptr2 = new int[0]; EXPECT_TRUE(NULL != int_ptr); @@ -394,7 +398,7 @@ TEST(AddressSanitizer, ZeroSizeMallocTest) { delete[] int_ptr2; } -#ifndef __APPLE__ +#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE static const char *kMallocUsableSizeErrorMsg = "AddressSanitizer: attempting to call malloc_usable_size()"; @@ -412,7 +416,7 @@ TEST(AddressSanitizer, MallocUsableSizeTest) { EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg); delete int_ptr; } -#endif +#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE void WrongFree() { int *x = (int*)malloc(100 * sizeof(int)); @@ -421,12 +425,14 @@ void WrongFree() { free(x + 1); } +#if !defined(_WIN32) // FIXME: This should be a lit test. TEST(AddressSanitizer, WrongFreeTest) { EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL "ERROR: AddressSanitizer: attempting free.*not malloc" ".*is located 4 bytes inside of 400-byte region" ".*allocated by thread"); } +#endif void DoubleFree() { int *x = (int*)malloc(100 * sizeof(int)); @@ -437,6 +443,7 @@ void DoubleFree() { abort(); } +#if !defined(_WIN32) // FIXME: This should be a lit test. TEST(AddressSanitizer, DoubleFreeTest) { EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL "ERROR: AddressSanitizer: attempting double-free" @@ -444,20 +451,22 @@ TEST(AddressSanitizer, DoubleFreeTest) { ".*freed by thread T0 here" ".*previously allocated by thread T0 here"); } +#endif template<int kSize> NOINLINE void SizedStackTest() { char a[kSize]; char *A = Ident((char*)&a); + const char *expected_death = "AddressSanitizer: stack-buffer-"; for (size_t i = 0; i < kSize; i++) A[i] = i; - EXPECT_DEATH(A[-1] = 0, ""); - EXPECT_DEATH(A[-20] = 0, ""); - EXPECT_DEATH(A[-31] = 0, ""); - EXPECT_DEATH(A[kSize] = 0, ""); - EXPECT_DEATH(A[kSize + 1] = 0, ""); - EXPECT_DEATH(A[kSize + 10] = 0, ""); - EXPECT_DEATH(A[kSize + 31] = 0, ""); + EXPECT_DEATH(A[-1] = 0, expected_death); + EXPECT_DEATH(A[-5] = 0, expected_death); + EXPECT_DEATH(A[kSize] = 0, expected_death); + EXPECT_DEATH(A[kSize + 1] = 0, expected_death); + EXPECT_DEATH(A[kSize + 5] = 0, expected_death); + if (kSize > 16) + EXPECT_DEATH(A[kSize + 31] = 0, expected_death); } TEST(AddressSanitizer, SimpleStackTest) { @@ -478,6 +487,9 @@ TEST(AddressSanitizer, SimpleStackTest) { SizedStackTest<128>(); } +#if !defined(_WIN32) +// FIXME: It's a bit hard to write multi-line death test expectations +// in a portable way. Anyways, this should just be turned into a lit test. TEST(AddressSanitizer, ManyStackObjectsTest) { char XXX[10]; char YYY[20]; @@ -486,6 +498,7 @@ TEST(AddressSanitizer, ManyStackObjectsTest) { Ident(YYY); EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ"); } +#endif #if 0 // This test requires online symbolizer. // Moved to lit_tests/stack-oob-frames.cc. @@ -538,6 +551,24 @@ NOINLINE void LongJmpFunc1(jmp_buf buf) { longjmp(buf, 1); } +NOINLINE void TouchStackFunc() { + int a[100]; // long array will intersect with redzones from LongJmpFunc1. + int *A = Ident(a); + for (int i = 0; i < 100; i++) + A[i] = i*i; +} + +// Test that we handle longjmp and do not report false positives on stack. +TEST(AddressSanitizer, LongJmpTest) { + static jmp_buf buf; + if (!setjmp(buf)) { + LongJmpFunc1(buf); + } else { + TouchStackFunc(); + } +} + +#if !defined(_WIN32) // Only basic longjmp is available on Windows. NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) { // create three red zones for these two stack objects. int a; @@ -571,27 +602,9 @@ NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) { siglongjmp(buf, 1); } - -NOINLINE void TouchStackFunc() { - int a[100]; // long array will intersect with redzones from LongJmpFunc1. - int *A = Ident(a); - for (int i = 0; i < 100; i++) - A[i] = i*i; -} - -// Test that we handle longjmp and do not report fals positives on stack. -TEST(AddressSanitizer, LongJmpTest) { - static jmp_buf buf; - if (!setjmp(buf)) { - LongJmpFunc1(buf); - } else { - TouchStackFunc(); - } -} - -#if !defined(__ANDROID__) && \ +#if !defined(__ANDROID__) && !defined(__arm__) && \ !defined(__powerpc64__) && !defined(__powerpc__) -// Does not work on Power: +// Does not work on Power and ARM: // https://code.google.com/p/address-sanitizer/issues/detail?id=185 TEST(AddressSanitizer, BuiltinLongJmpTest) { static jmp_buf buf; @@ -601,7 +614,8 @@ TEST(AddressSanitizer, BuiltinLongJmpTest) { TouchStackFunc(); } } -#endif // not defined(__ANDROID__) +#endif // !defined(__ANDROID__) && !defined(__powerpc64__) && + // !defined(__powerpc__) && !defined(__arm__) TEST(AddressSanitizer, UnderscopeLongJmpTest) { static jmp_buf buf; @@ -620,8 +634,10 @@ TEST(AddressSanitizer, SigLongJmpTest) { TouchStackFunc(); } } +#endif -#ifdef __EXCEPTIONS +// FIXME: Why does clang-cl define __EXCEPTIONS? +#if defined(__EXCEPTIONS) && !defined(_WIN32) NOINLINE void ThrowFunc() { // create three red zones for these two stack objects. int a; @@ -688,12 +704,19 @@ TEST(AddressSanitizer, Store128Test) { } #endif +// FIXME: All tests that use this function should be turned into lit tests. string RightOOBErrorMessage(int oob_distance, bool is_write) { assert(oob_distance >= 0); char expected_str[100]; sprintf(expected_str, ASAN_PCRE_DOTALL - "buffer-overflow.*%s.*located %d bytes to the right", - is_write ? "WRITE" : "READ", oob_distance); +#if !GTEST_USES_SIMPLE_RE + "buffer-overflow.*%s.*" +#endif + "located %d bytes to the right", +#if !GTEST_USES_SIMPLE_RE + is_write ? "WRITE" : "READ", +#endif + oob_distance); return string(expected_str); } @@ -705,11 +728,19 @@ string RightOOBReadMessage(int oob_distance) { return RightOOBErrorMessage(oob_distance, /*is_write*/false); } +// FIXME: All tests that use this function should be turned into lit tests. string LeftOOBErrorMessage(int oob_distance, bool is_write) { assert(oob_distance > 0); char expected_str[100]; - sprintf(expected_str, ASAN_PCRE_DOTALL "%s.*located %d bytes to the left", - is_write ? "WRITE" : "READ", oob_distance); + sprintf(expected_str, +#if !GTEST_USES_SIMPLE_RE + ASAN_PCRE_DOTALL "%s.*" +#endif + "located %d bytes to the left", +#if !GTEST_USES_SIMPLE_RE + is_write ? "WRITE" : "READ", +#endif + oob_distance); return string(expected_str); } @@ -738,7 +769,7 @@ char* MallocAndMemsetString(size_t size) { return MallocAndMemsetString(size, 'z'); } -#if defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__) +#if defined(__linux__) && !defined(__ANDROID__) #define READ_TEST(READ_N_BYTES) \ char *x = new char[10]; \ int fd = open("/proc/self/stat", O_RDONLY); \ @@ -761,7 +792,7 @@ TEST(AddressSanitizer, pread64) { TEST(AddressSanitizer, read) { READ_TEST(read(fd, x, 15)); } -#endif // defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__) +#endif // defined(__linux__) && !defined(__ANDROID__) // This test case fails // Clang optimizes memcpy/memset calls which lead to unaligned access @@ -801,7 +832,7 @@ NOINLINE static int LargeFunction(bool do_bad_access) { x[18]++; x[19]++; - delete x; + delete[] x; return res; } @@ -863,6 +894,7 @@ void ThreadedTestSpawn() { PTHREAD_JOIN(t, 0); } +#if !defined(_WIN32) // FIXME: This should be a lit test. TEST(AddressSanitizer, ThreadedTest) { EXPECT_DEATH(ThreadedTestSpawn(), ASAN_PCRE_DOTALL @@ -870,6 +902,7 @@ TEST(AddressSanitizer, ThreadedTest) { ".*Thread T.*created" ".*Thread T.*created"); } +#endif void *ThreadedTestFunc(void *unused) { // Check if prctl(PR_SET_NAME) is supported. Return if not. @@ -1064,7 +1097,8 @@ TEST(AddressSanitizer, PthreadExitTest) { } } -#ifdef __EXCEPTIONS +// FIXME: Why does clang-cl define __EXCEPTIONS? +#if defined(__EXCEPTIONS) && !defined(_WIN32) NOINLINE static void StackReuseAndException() { int large_stack[1000]; Ident(large_stack); @@ -1082,12 +1116,14 @@ TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) { } #endif +#if !defined(_WIN32) TEST(AddressSanitizer, MlockTest) { EXPECT_EQ(0, mlockall(MCL_CURRENT)); EXPECT_EQ(0, mlock((void*)0x12345, 0x5678)); EXPECT_EQ(0, munlockall()); EXPECT_EQ(0, munlock((void*)0x987, 0x654)); } +#endif struct LargeStruct { int foo[100]; @@ -1111,10 +1147,15 @@ TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) { Ident(NoSanitizeAddress)(); } -// It doesn't work on Android, as calls to new/delete go through malloc/free. -// Neither it does on OS X, see -// https://code.google.com/p/address-sanitizer/issues/detail?id=131. -#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(__APPLE__) +// The new/delete/etc mismatch checks don't work on Android, +// as calls to new/delete go through malloc/free. +// OS X support is tracked here: +// https://code.google.com/p/address-sanitizer/issues/detail?id=131 +// Windows support is tracked here: +// https://code.google.com/p/address-sanitizer/issues/detail?id=309 +#if !defined(__ANDROID__) && \ + !defined(__APPLE__) && \ + !defined(_WIN32) static string MismatchStr(const string &str) { return string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str; } @@ -1229,6 +1270,7 @@ TEST(AddressSanitizer, LongDoubleNegativeTest) { memcpy(Ident(&c), Ident(&b), sizeof(long double)); } +#if !defined(_WIN32) TEST(AddressSanitizer, pthread_getschedparam) { int policy; struct sched_param param; @@ -1241,3 +1283,4 @@ TEST(AddressSanitizer, pthread_getschedparam) { int res = pthread_getschedparam(pthread_self(), &policy, ¶m); ASSERT_EQ(0, res); } +#endif diff --git a/lib/asan/tests/asan_test_config.h b/lib/asan/tests/asan_test_config.h index 6eb33ce4431b8..92f276307481f 100644 --- a/lib/asan/tests/asan_test_config.h +++ b/lib/asan/tests/asan_test_config.h @@ -21,12 +21,6 @@ #include <string> #include <map> -#if ASAN_USE_DEJAGNU_GTEST -# include "dejagnu-gtest.h" -#else -# include "gtest/gtest.h" -#endif - using std::string; using std::vector; using std::map; @@ -44,7 +38,11 @@ using std::map; #endif #ifndef ASAN_NEEDS_SEGV -# error "please define ASAN_NEEDS_SEGV" +# if defined(_WIN32) +# define ASAN_NEEDS_SEGV 0 +# else +# define ASAN_NEEDS_SEGV 1 +# endif #endif #ifndef ASAN_AVOID_EXPENSIVE_TESTS diff --git a/lib/asan/tests/asan_test_utils.h b/lib/asan/tests/asan_test_utils.h index b6bf6b82066dc..03d17cfb26a75 100644 --- a/lib/asan/tests/asan_test_utils.h +++ b/lib/asan/tests/asan_test_utils.h @@ -14,24 +14,28 @@ #ifndef ASAN_TEST_UTILS_H #define ASAN_TEST_UTILS_H -#if !defined(ASAN_EXTERNAL_TEST_CONFIG) +#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG) # define INCLUDED_FROM_ASAN_TEST_UTILS_H # include "asan_test_config.h" # undef INCLUDED_FROM_ASAN_TEST_UTILS_H #endif #include "sanitizer_test_utils.h" +#include "sanitizer_pthread_wrappers.h" + #include <stdio.h> #include <signal.h> #include <stdlib.h> #include <string.h> -#include <strings.h> -#include <pthread.h> #include <stdint.h> -#include <setjmp.h> #include <assert.h> #include <algorithm> -#include <sys/mman.h> + +#if !defined(_WIN32) +# include <strings.h> +# include <sys/mman.h> +# include <setjmp.h> +#endif #ifdef __linux__ # include <sys/prctl.h> @@ -41,14 +45,10 @@ #include <unistd.h> #endif -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(__FreeBSD__) #include <malloc.h> #endif -// Check that pthread_create/pthread_join return success. -#define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d)) -#define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b)) - #if ASAN_HAS_EXCEPTIONS # define ASAN_THROW(x) throw (x) #else |