diff options
Diffstat (limited to 'lib/asan/lit_tests')
160 files changed, 2049 insertions, 1097 deletions
diff --git a/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in b/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in new file mode 100644 index 000000000000..faef4e8c9b17 --- /dev/null +++ b/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in @@ -0,0 +1,13 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! + +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured") + +# Tool-specific config options. +config.asan_source_dir = "@ASAN_SOURCE_DIR@" +config.bits = "32" + +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/lit.cfg") + diff --git a/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in b/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in new file mode 100644 index 000000000000..a35994484d5f --- /dev/null +++ b/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in @@ -0,0 +1,12 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! + +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured") + +# Tool-specific config options. +config.asan_source_dir = "@ASAN_SOURCE_DIR@" +config.bits = "64" + +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/lit.cfg") diff --git a/lib/asan/lit_tests/CMakeLists.txt b/lib/asan/lit_tests/CMakeLists.txt index d2420b50da83..72a3f5439b70 100644 --- a/lib/asan/lit_tests/CMakeLists.txt +++ b/lib/asan/lit_tests/CMakeLists.txt @@ -2,8 +2,13 @@ set(ASAN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) set(ASAN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/..) configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ${CMAKE_CURRENT_SOURCE_DIR}/64bitConfig/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig/lit.site.cfg + ) + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/32bitConfig/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig/lit.site.cfg ) configure_lit_site_cfg( @@ -12,21 +17,26 @@ configure_lit_site_cfg( ) if(COMPILER_RT_CAN_EXECUTE_TESTS) + set(ASAN_TESTSUITES) + if(CAN_TARGET_i386) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig) + endif() + if(CAN_TARGET_x86_64 OR CAN_TARGET_powerpc64) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig) + endif() # Run ASan tests only if we're sure we may produce working binaries. set(ASAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} - ${ASAN_RUNTIME_LIBRARIES} - asan_blacklist) + asan_runtime_libraries) set(ASAN_TEST_PARAMS - asan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg - ) + asan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg) if(LLVM_INCLUDE_TESTS) list(APPEND ASAN_TEST_DEPS AsanUnitTests) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit) endif() add_lit_testsuite(check-asan "Running the AddressSanitizer tests" - ${CMAKE_CURRENT_BINARY_DIR} + ${ASAN_TESTSUITES} PARAMS ${ASAN_TEST_PARAMS} - DEPENDS ${ASAN_TEST_DEPS} - ) + DEPENDS ${ASAN_TEST_DEPS}) set_target_properties(check-asan PROPERTIES FOLDER "ASan tests") endif() diff --git a/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc b/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc deleted file mode 100644 index cf89949cf942..000000000000 --- a/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Make sure ASan removes the runtime library from DYLD_INSERT_LIBRARIES before -// executing other programs. - -// RUN: %clangxx_asan -m64 %s -o %t -// RUN: %clangxx -m64 %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ -// RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib - -// Make sure DYLD_INSERT_LIBRARIES doesn't contain the runtime library before -// execl(). - -// RUN: %t >/dev/null 2>&1 -// RUN: DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \ -// RUN: %t 2>&1 | FileCheck %s || exit 1 -#include <unistd.h> -int main() { - execl("/bin/bash", "/bin/bash", "-c", - "echo DYLD_INSERT_LIBRARIES=$DYLD_INSERT_LIBRARIES", NULL); - // CHECK: {{DYLD_INSERT_LIBRARIES=.*darwin-dummy-shared-lib-so.dylib.*}} - return 0; -} diff --git a/lib/asan/lit_tests/Helpers/initialization-blacklist.txt b/lib/asan/lit_tests/Helpers/initialization-blacklist.txt deleted file mode 100644 index fa4a83667f4b..000000000000 --- a/lib/asan/lit_tests/Helpers/initialization-blacklist.txt +++ /dev/null @@ -1,3 +0,0 @@ -global-init:*badGlobal* -global-init-type:*badNamespace::BadClass* -global-init-src:*initialization-blacklist-extra2.cc diff --git a/lib/asan/lit_tests/Linux/interception_failure_test.cc b/lib/asan/lit_tests/Linux/interception_failure_test.cc deleted file mode 100644 index dfad909f528c..000000000000 --- a/lib/asan/lit_tests/Linux/interception_failure_test.cc +++ /dev/null @@ -1,26 +0,0 @@ -// If user provides his own libc functions, ASan doesn't -// intercept these functions. - -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s -#include <stdlib.h> -#include <stdio.h> - -extern "C" long strtol(const char *nptr, char **endptr, int base) { - fprintf(stderr, "my_strtol_interceptor\n"); - return 0; -} - -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return (int)strtol(x, 0, 10); - // CHECK: my_strtol_interceptor - // CHECK-NOT: heap-use-after-free -} diff --git a/lib/asan/lit_tests/Linux/interception_malloc_test.cc b/lib/asan/lit_tests/Linux/interception_malloc_test.cc deleted file mode 100644 index 8f66788e9a82..000000000000 --- a/lib/asan/lit_tests/Linux/interception_malloc_test.cc +++ /dev/null @@ -1,27 +0,0 @@ -// ASan interceptor can be accessed with __interceptor_ prefix. - -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> - -extern "C" void *__interceptor_malloc(size_t size); -extern "C" void *malloc(size_t size) { - write(2, "malloc call\n", sizeof("malloc call\n") - 1); - return __interceptor_malloc(size); -} - -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return (int)strtol(x, 0, 10); - // CHECK: malloc call - // CHECK: heap-use-after-free -} diff --git a/lib/asan/lit_tests/Linux/interception_test.cc b/lib/asan/lit_tests/Linux/interception_test.cc deleted file mode 100644 index 94fb499f2f87..000000000000 --- a/lib/asan/lit_tests/Linux/interception_test.cc +++ /dev/null @@ -1,26 +0,0 @@ -// ASan interceptor can be accessed with __interceptor_ prefix. - -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s -#include <stdlib.h> -#include <stdio.h> - -extern "C" long __interceptor_strtol(const char *nptr, char **endptr, int base); -extern "C" long strtol(const char *nptr, char **endptr, int base) { - fprintf(stderr, "my_strtol_interceptor\n"); - return __interceptor_strtol(nptr, endptr, base); -} - -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return (int)strtol(x, 0, 10); - // CHECK: my_strtol_interceptor - // CHECK: heap-use-after-free -} diff --git a/lib/asan/lit_tests/Linux/zero-base-shadow.cc b/lib/asan/lit_tests/Linux/zero-base-shadow.cc deleted file mode 100644 index 682e7e8d7e59..000000000000 --- a/lib/asan/lit_tests/Linux/zero-base-shadow.cc +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out -// RUN: %clangxx_asan -m64 -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out -// RUN: %clangxx_asan -m64 -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out -// RUN: %clangxx_asan -m32 -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out -// RUN: %clangxx_asan -m32 -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out -// RUN: %clangxx_asan -m32 -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out - -// Zero-base shadow only works on x86_64 and i386. -// REQUIRES: x86_64-supported-target,i386-supported-target - -#include <string.h> -int main(int argc, char **argv) { - char x[10]; - memset(x, 0, 10); - int res = x[argc * 10]; // BOOOM - // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in _?main .*zero-base-shadow.cc:}}[[@LINE-2]] - // CHECK: {{Address 0x.* is .* frame}} - // CHECK: main - - // Check that shadow for stack memory occupies lower part of address space. - // CHECK-64: =>0x0f - // CHECK-32: =>0x1 - return res; -} diff --git a/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c b/lib/asan/lit_tests/TestCases/Darwin/interface_symbols_darwin.c index 3fca6e915324..b453b64cafd2 100644 --- a/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c +++ b/lib/asan/lit_tests/TestCases/Darwin/interface_symbols_darwin.c @@ -2,7 +2,7 @@ // If you're changing this file, please also change // ../Linux/interface_symbols.c -// RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe +// RUN: %clang_asan -dead_strip -O2 %s -o %t.exe // RUN: rm -f %t.symbols %t.interface // RUN: nm -g `otool -L %t.exe | grep "asan_osx_dynamic.dylib" | \ @@ -16,7 +16,7 @@ // RUN: | grep -v "__asan_default_options" \ // RUN: | grep -v "__asan_on_error" > %t.symbols -// RUN: cat %p/../../asan_interface_internal.h \ +// RUN: cat %p/../../../asan_interface_internal.h \ // RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \ // RUN: | grep -v "OPTIONAL" \ // RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \ @@ -33,6 +33,8 @@ // RUN: echo __asan_report_store16 >> %t.interface // RUN: echo __asan_report_load_n >> %t.interface // RUN: echo __asan_report_store_n >> %t.interface +// RUN: for i in `jot - 0 10`; do echo __asan_stack_malloc_$i >> %t.interface; done +// RUN: for i in `jot - 0 10`; do echo __asan_stack_free_$i >> %t.interface; done // RUN: cat %t.interface | sort -u | diff %t.symbols - diff --git a/lib/asan/lit_tests/Darwin/lit.local.cfg b/lib/asan/lit_tests/TestCases/Darwin/lit.local.cfg index a85dfcd24c08..a85dfcd24c08 100644 --- a/lib/asan/lit_tests/Darwin/lit.local.cfg +++ b/lib/asan/lit_tests/TestCases/Darwin/lit.local.cfg diff --git a/lib/asan/lit_tests/TestCases/Darwin/malloc_set_zone_name-mprotect.cc b/lib/asan/lit_tests/TestCases/Darwin/malloc_set_zone_name-mprotect.cc new file mode 100644 index 000000000000..807a8283e788 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Darwin/malloc_set_zone_name-mprotect.cc @@ -0,0 +1,51 @@ +// Regression test for a bug in malloc_create_zone() +// (https://code.google.com/p/address-sanitizer/issues/detail?id=203) +// The old implementation of malloc_create_zone() didn't always return a +// page-aligned address, so we can only test on a best-effort basis. + +// RUN: %clangxx_asan %s -o %t +// RUN: %t 2>&1 + +#include <malloc/malloc.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +const int kNumIter = 4096; +const int kNumZones = 100; +int main() { + char *mem[kNumIter * 2]; + // Allocate memory chunks from different size classes up to 1 page. + // (For the case malloc() returns memory chunks in descending order) + for (int i = 0; i < kNumIter; i++) { + mem[i] = (char*)malloc(8 * i); + } + // Try to allocate a page-aligned malloc zone. Otherwise the mprotect() call + // in malloc_set_zone_name() will silently fail. + malloc_zone_t *zone = NULL; + bool aligned = false; + for (int i = 0; i < kNumZones; i++) { + zone = malloc_create_zone(0, 0); + if (((uintptr_t)zone & (~0xfff)) == (uintptr_t)zone) { + aligned = true; + break; + } + } + if (!aligned) { + printf("Warning: couldn't allocate a page-aligned zone."); + return 0; + } + // malloc_set_zone_name() calls mprotect(zone, 4096, PROT_READ | PROT_WRITE), + // modifies the zone contents and then calls mprotect(zone, 4096, PROT_READ). + malloc_set_zone_name(zone, "foobar"); + // Allocate memory chunks from different size classes again. + for (int i = 0; i < kNumIter; i++) { + mem[i + kNumIter] = (char*)malloc(8 * i); + } + // Access the allocated memory chunks and free them. + for (int i = 0; i < kNumIter * 2; i++) { + memset(mem[i], 'a', 8 * (i % kNumIter)); + free(mem[i]); + } + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/Darwin/malloc_zone-protected.cc b/lib/asan/lit_tests/TestCases/Darwin/malloc_zone-protected.cc new file mode 100644 index 000000000000..d5f6c7c12e67 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Darwin/malloc_zone-protected.cc @@ -0,0 +1,20 @@ +// Make sure the zones created by malloc_create_zone() are write-protected. +#include <malloc/malloc.h> +#include <stdio.h> + +// RUN: %clangxx_asan %s -o %t +// RUN: not %t 2>&1 | FileCheck %s + + +void *pwn(malloc_zone_t *unused_zone, size_t unused_size) { + printf("PWNED\n"); + return NULL; +} + +int main() { + malloc_zone_t *zone = malloc_create_zone(0, 0); + zone->malloc = pwn; + void *v = malloc_zone_malloc(zone, 1); + // CHECK-NOT: PWNED + return 0; +} diff --git a/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc b/lib/asan/lit_tests/TestCases/Darwin/reexec-insert-libraries-env.cc index 40a459fd84db..208fe43ac7e4 100644 --- a/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc +++ b/lib/asan/lit_tests/TestCases/Darwin/reexec-insert-libraries-env.cc @@ -2,8 +2,8 @@ // This is a regression test for // https://code.google.com/p/address-sanitizer/issues/detail?id=159 -// RUN: %clangxx_asan -m64 %s -o %t -// RUN: %clangxx -m64 %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ +// RUN: %clangxx_asan %s -o %t +// RUN: %clangxx %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ // RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib // FIXME: the following command line may hang in the case of a regression. diff --git a/lib/asan/lit_tests/TestCases/Darwin/unset-insert-libraries-on-exec.cc b/lib/asan/lit_tests/TestCases/Darwin/unset-insert-libraries-on-exec.cc new file mode 100644 index 000000000000..fa0dd4f9df88 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Darwin/unset-insert-libraries-on-exec.cc @@ -0,0 +1,20 @@ +// Make sure ASan removes the runtime library from DYLD_INSERT_LIBRARIES before +// executing other programs. + +// RUN: %clangxx_asan %s -o %t +// RUN: %clangxx %p/../Helpers/echo-env.cc -o %T/echo-env +// RUN: %clangxx %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ +// RUN: -dynamiclib -o %t-darwin-dummy-shared-lib-so.dylib + +// Make sure DYLD_INSERT_LIBRARIES doesn't contain the runtime library before +// execl(). + +// RUN: %t %T/echo-env >/dev/null 2>&1 +// RUN: DYLD_INSERT_LIBRARIES=%t-darwin-dummy-shared-lib-so.dylib \ +// RUN: %t %T/echo-env 2>&1 | FileCheck %s || exit 1 +#include <unistd.h> +int main(int argc, char *argv[]) { + execl(argv[1], argv[1], "DYLD_INSERT_LIBRARIES", NULL); + // CHECK: {{DYLD_INSERT_LIBRARIES = .*darwin-dummy-shared-lib-so.dylib.*}} + return 0; +} diff --git a/lib/asan/lit_tests/Helpers/blacklist-extra.cc b/lib/asan/lit_tests/TestCases/Helpers/blacklist-extra.cc index 627115cdda2b..627115cdda2b 100644 --- a/lib/asan/lit_tests/Helpers/blacklist-extra.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/blacklist-extra.cc diff --git a/lib/asan/lit_tests/TestCases/Helpers/echo-env.cc b/lib/asan/lit_tests/TestCases/Helpers/echo-env.cc new file mode 100644 index 000000000000..65e91c155c84 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Helpers/echo-env.cc @@ -0,0 +1,19 @@ +// Helper binary for +// lit_tests/TestCases/Darwin/unset-insert-libraries-on-exec.cc +// Prints the environment variable with the given name. +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char *argv[]) { + if (argc != 2) { + printf("Usage: %s ENVNAME\n", argv[0]); + exit(1); + } + const char *value = getenv(argv[1]); + if (value) { + printf("%s = %s\n", argv[1], value); + } else { + printf("%s not set.\n", argv[1]); + } + return 0; +} diff --git a/lib/asan/lit_tests/Helpers/init-order-atexit-extra.cc b/lib/asan/lit_tests/TestCases/Helpers/init-order-atexit-extra.cc index e4189d19d099..e4189d19d099 100644 --- a/lib/asan/lit_tests/Helpers/init-order-atexit-extra.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/init-order-atexit-extra.cc diff --git a/lib/asan/lit_tests/TestCases/Helpers/init-order-pthread-create-extra.cc b/lib/asan/lit_tests/TestCases/Helpers/init-order-pthread-create-extra.cc new file mode 100644 index 000000000000..d4606f0afb52 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Helpers/init-order-pthread-create-extra.cc @@ -0,0 +1,2 @@ +void *bar(void *input); +void *glob2 = bar((void*)0x2345); diff --git a/lib/asan/lit_tests/Helpers/initialization-blacklist-extra.cc b/lib/asan/lit_tests/TestCases/Helpers/initialization-blacklist-extra.cc index 09aed2112d5e..09aed2112d5e 100644 --- a/lib/asan/lit_tests/Helpers/initialization-blacklist-extra.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/initialization-blacklist-extra.cc diff --git a/lib/asan/lit_tests/Helpers/initialization-blacklist-extra2.cc b/lib/asan/lit_tests/TestCases/Helpers/initialization-blacklist-extra2.cc index 69455a0a6fc9..69455a0a6fc9 100644 --- a/lib/asan/lit_tests/Helpers/initialization-blacklist-extra2.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/initialization-blacklist-extra2.cc diff --git a/lib/asan/lit_tests/TestCases/Helpers/initialization-blacklist.txt b/lib/asan/lit_tests/TestCases/Helpers/initialization-blacklist.txt new file mode 100644 index 000000000000..83294635622d --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Helpers/initialization-blacklist.txt @@ -0,0 +1,3 @@ +global:*badGlobal*=init +type:*badNamespace::BadClass*=init +src:*initialization-blacklist-extra2.cc=init diff --git a/lib/asan/lit_tests/Helpers/initialization-bug-extra.cc b/lib/asan/lit_tests/TestCases/Helpers/initialization-bug-extra.cc index 3c4cb411defa..3c4cb411defa 100644 --- a/lib/asan/lit_tests/Helpers/initialization-bug-extra.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/initialization-bug-extra.cc diff --git a/lib/asan/lit_tests/Helpers/initialization-bug-extra2.cc b/lib/asan/lit_tests/TestCases/Helpers/initialization-bug-extra2.cc index a3d8f190e58b..a3d8f190e58b 100644 --- a/lib/asan/lit_tests/Helpers/initialization-bug-extra2.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/initialization-bug-extra2.cc diff --git a/lib/asan/lit_tests/Helpers/initialization-constexpr-extra.cc b/lib/asan/lit_tests/TestCases/Helpers/initialization-constexpr-extra.cc index b32466a981b3..b32466a981b3 100644 --- a/lib/asan/lit_tests/Helpers/initialization-constexpr-extra.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/initialization-constexpr-extra.cc diff --git a/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc b/lib/asan/lit_tests/TestCases/Helpers/initialization-nobug-extra.cc index 886165affd76..886165affd76 100644 --- a/lib/asan/lit_tests/Helpers/initialization-nobug-extra.cc +++ b/lib/asan/lit_tests/TestCases/Helpers/initialization-nobug-extra.cc diff --git a/lib/asan/lit_tests/Helpers/lit.local.cfg b/lib/asan/lit_tests/TestCases/Helpers/lit.local.cfg index 2fc4d99456b0..2fc4d99456b0 100644 --- a/lib/asan/lit_tests/Helpers/lit.local.cfg +++ b/lib/asan/lit_tests/TestCases/Helpers/lit.local.cfg diff --git a/lib/asan/lit_tests/Linux/asan_prelink_test.cc b/lib/asan/lit_tests/TestCases/Linux/asan_prelink_test.cc index c209c39c8c42..0f158c1bb3dd 100644 --- a/lib/asan/lit_tests/Linux/asan_prelink_test.cc +++ b/lib/asan/lit_tests/TestCases/Linux/asan_prelink_test.cc @@ -3,13 +3,13 @@ // or gold's flag -Ttext (we try the first flag first, if that fails we // try the second flag). // -// RUN: %clangxx_asan -m64 -c %s -o %t.o -// RUN: %clangxx_asan -m64 -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext-segment=0x3600000000 ||\ -// RUN: %clangxx_asan -m64 -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext=0x3600000000 -// RUN: %clangxx_asan -m64 %t.o %t.so -Wl,-R. -o %t +// RUN: %clangxx_asan -c %s -o %t.o +// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext-segment=0x3600000000 ||\ +// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext=0x3600000000 +// RUN: %clangxx_asan %t.o %t.so -Wl,-R. -o %t // RUN: ASAN_OPTIONS=verbosity=1 %t 2>&1 | FileCheck %s -// REQUIRES: x86_64-supported-target +// REQUIRES: x86_64-supported-target, asan-64-bits #if BUILD_SO int G; int *getG() { diff --git a/lib/asan/lit_tests/Linux/clone_test.cc b/lib/asan/lit_tests/TestCases/Linux/clone_test.cc index ca13b22425f2..0e12f35b400a 100644 --- a/lib/asan/lit_tests/Linux/clone_test.cc +++ b/lib/asan/lit_tests/TestCases/Linux/clone_test.cc @@ -1,14 +1,10 @@ // Regression test for: // http://code.google.com/p/address-sanitizer/issues/detail?id=37 -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && %t | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && %t | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && %t | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && %t | FileCheck %s #include <stdio.h> #include <sched.h> diff --git a/lib/asan/lit_tests/TestCases/Linux/coverage.cc b/lib/asan/lit_tests/TestCases/Linux/coverage.cc new file mode 100644 index 000000000000..4373e9b13c68 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/coverage.cc @@ -0,0 +1,45 @@ +// RUN: %clangxx_asan -mllvm -asan-coverage=1 -DSHARED %s -shared -o %t.so -fPIC +// RUN: %clangxx_asan -mllvm -asan-coverage=1 %s -o %t -Wl,-R. %t.so +// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1 +// RUN: %t 2>&1 | FileCheck %s --check-prefix=CHECK-main +// RUN: %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-foo +// RUN: %t bar 2>&1 | FileCheck %s --check-prefix=CHECK-bar +// RUN: %t foo bar 2>&1 | FileCheck %s --check-prefix=CHECK-foo-bar + +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#ifdef SHARED +void bar() { printf("bar\n"); } +#else +__attribute__((noinline)) +void foo() { printf("foo\n"); } +extern void bar(); + +int main(int argc, char **argv) { + fprintf(stderr, "PID: %d\n", getpid()); + for (int i = 1; i < argc; i++) { + if (!strcmp(argv[i], "foo")) + foo(); + if (!strcmp(argv[i], "bar")) + bar(); + } +} +#endif + +// CHECK-main: PID: [[PID:[0-9]+]] +// CHECK-main: [[PID]].sancov: 1 PCs written +// CHECK-main-NOT: .so.[[PID]] +// +// CHECK-foo: PID: [[PID:[0-9]+]] +// CHECK-foo: [[PID]].sancov: 2 PCs written +// CHECK-foo-NOT: .so.[[PID]] +// +// CHECK-bar: PID: [[PID:[0-9]+]] +// CHECK-bar: [[PID]].sancov: 1 PCs written +// CHECK-bar: .so.[[PID]].sancov: 1 PCs written +// +// CHECK-foo-bar: PID: [[PID:[0-9]+]] +// CHECK-foo-bar: [[PID]].sancov: 2 PCs written +// CHECK-foo-bar: so.[[PID]].sancov: 1 PCs written diff --git a/lib/asan/lit_tests/Linux/glob.cc b/lib/asan/lit_tests/TestCases/Linux/glob.cc index e05228ff39e3..123768b099ed 100644 --- a/lib/asan/lit_tests/Linux/glob.cc +++ b/lib/asan/lit_tests/TestCases/Linux/glob.cc @@ -1,7 +1,5 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && %t %p 2>&1 | FileCheck %s #include <assert.h> #include <glob.h> @@ -24,6 +22,7 @@ int main(int argc, char *argv[]) { assert(globbuf.gl_pathc == 2); printf("%zu\n", strlen(globbuf.gl_pathv[0])); printf("%zu\n", strlen(globbuf.gl_pathv[1])); + globfree(&globbuf); printf("PASS\n"); // CHECK: PASS return 0; diff --git a/lib/asan/lit_tests/Linux/glob_test_root/aa b/lib/asan/lit_tests/TestCases/Linux/glob_test_root/aa index e69de29bb2d1..e69de29bb2d1 100644 --- a/lib/asan/lit_tests/Linux/glob_test_root/aa +++ b/lib/asan/lit_tests/TestCases/Linux/glob_test_root/aa diff --git a/lib/asan/lit_tests/Linux/glob_test_root/ab b/lib/asan/lit_tests/TestCases/Linux/glob_test_root/ab index e69de29bb2d1..e69de29bb2d1 100644 --- a/lib/asan/lit_tests/Linux/glob_test_root/ab +++ b/lib/asan/lit_tests/TestCases/Linux/glob_test_root/ab diff --git a/lib/asan/lit_tests/Linux/glob_test_root/ba b/lib/asan/lit_tests/TestCases/Linux/glob_test_root/ba index e69de29bb2d1..e69de29bb2d1 100644 --- a/lib/asan/lit_tests/Linux/glob_test_root/ba +++ b/lib/asan/lit_tests/TestCases/Linux/glob_test_root/ba diff --git a/lib/asan/lit_tests/TestCases/Linux/heap-overflow-large.cc b/lib/asan/lit_tests/TestCases/Linux/heap-overflow-large.cc new file mode 100644 index 000000000000..67e9c3718d59 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/heap-overflow-large.cc @@ -0,0 +1,23 @@ +// Regression test for +// https://code.google.com/p/address-sanitizer/issues/detail?id=183 + +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: not %t 12 2>&1 | FileCheck %s +// RUN: not %t 100 2>&1 | FileCheck %s +// RUN: not %t 10000 2>&1 | FileCheck %s + +#include <stdlib.h> +#include <string.h> + +int main(int argc, char *argv[]) { + int *x = new int[5]; + memset(x, 0, sizeof(x[0]) * 5); + int index = atoi(argv[1]); + int res = x[index]; + // CHECK: AddressSanitizer: {{(heap-buffer-overflow|SEGV)}} + // CHECK: #0 0x{{.*}} in main {{.*}}heap-overflow-large.cc:[[@LINE-2]] + // CHECK: AddressSanitizer can not {{(provide additional info|describe address in more detail \(wild memory access suspected\))}} + // CHECK: SUMMARY: AddressSanitizer: {{(heap-buffer-overflow|SEGV)}} + delete[] x; + return res; +} diff --git a/lib/asan/lit_tests/Linux/heavy_uar_test.cc b/lib/asan/lit_tests/TestCases/Linux/heavy_uar_test.cc index c0f4560fb4e7..27b179e83624 100644 --- a/lib/asan/lit_tests/Linux/heavy_uar_test.cc +++ b/lib/asan/lit_tests/TestCases/Linux/heavy_uar_test.cc @@ -1,9 +1,8 @@ -// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O0 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O2 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m32 -O2 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s +// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: %clangxx_asan -O0 %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s #include <stdio.h> #include <string.h> diff --git a/lib/asan/lit_tests/Linux/initialization-bug-any-order.cc b/lib/asan/lit_tests/TestCases/Linux/initialization-bug-any-order.cc index 4f41dda18128..042a07e428d9 100644 --- a/lib/asan/lit_tests/Linux/initialization-bug-any-order.cc +++ b/lib/asan/lit_tests/TestCases/Linux/initialization-bug-any-order.cc @@ -3,12 +3,10 @@ // independently on order in which we list source files (if we specify // strict init-order checking). -// RUN: %clangxx_asan -m64 -O0 %s %p/../Helpers/initialization-bug-extra.cc -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 \ -// RUN: | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O0 %p/../Helpers/initialization-bug-extra.cc %s -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 \ -// RUN: | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s %p/../Helpers/initialization-bug-extra.cc -o %t +// RUN: ASAN_OPTIONS=strict_init_order=true not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %p/../Helpers/initialization-bug-extra.cc %s -o %t +// RUN: ASAN_OPTIONS=strict_init_order=true not %t 2>&1 | FileCheck %s // Do not test with optimization -- the error may be optimized away. diff --git a/lib/asan/lit_tests/TestCases/Linux/interception_failure_test.cc b/lib/asan/lit_tests/TestCases/Linux/interception_failure_test.cc new file mode 100644 index 000000000000..9d161aa2dccb --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/interception_failure_test.cc @@ -0,0 +1,22 @@ +// If user provides his own libc functions, ASan doesn't +// intercept these functions. + +// RUN: %clangxx_asan -O0 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && %t 2>&1 | FileCheck %s +#include <stdlib.h> +#include <stdio.h> + +extern "C" long strtol(const char *nptr, char **endptr, int base) { + fprintf(stderr, "my_strtol_interceptor\n"); + return 0; +} + +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return (int)strtol(x, 0, 10); + // CHECK: my_strtol_interceptor + // CHECK-NOT: heap-use-after-free +} diff --git a/lib/asan/lit_tests/TestCases/Linux/interception_malloc_test.cc b/lib/asan/lit_tests/TestCases/Linux/interception_malloc_test.cc new file mode 100644 index 000000000000..cdd7239ab7bc --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/interception_malloc_test.cc @@ -0,0 +1,23 @@ +// ASan interceptor can be accessed with __interceptor_ prefix. + +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +extern "C" void *__interceptor_malloc(size_t size); +extern "C" void *malloc(size_t size) { + write(2, "malloc call\n", sizeof("malloc call\n") - 1); + return __interceptor_malloc(size); +} + +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return (int)strtol(x, 0, 10); + // CHECK: malloc call + // CHECK: heap-use-after-free +} diff --git a/lib/asan/lit_tests/TestCases/Linux/interception_readdir_r_test.cc b/lib/asan/lit_tests/TestCases/Linux/interception_readdir_r_test.cc new file mode 100644 index 000000000000..198e1f3884dd --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/interception_readdir_r_test.cc @@ -0,0 +1,59 @@ +// RUN: %clangxx_asan -O0 %s -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s +// +// RUN: %clangxx_asan -O0 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %t 2>&1 | FileCheck %s + +#include <dirent.h> +#include <memory.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +int main() { + // Ensure the readdir_r interceptor doesn't erroneously mark the entire dirent + // as written when the end of the directory pointer is reached. + fputs("test1: reading the " TEMP_DIR " directory...\n", stderr); + DIR *d = opendir(TEMP_DIR); + struct dirent *result = (struct dirent *)(0xfeedbeef); + // We assume the temp dir for this test doesn't have crazy long file names. + char entry_buffer[4096]; + memset(entry_buffer, 0xab, sizeof(entry_buffer)); + unsigned count = 0; + do { + // Stamp the entry struct to try to trick the interceptor. + ((struct dirent *)entry_buffer)->d_reclen = 9999; + if (readdir_r(d, (struct dirent *)entry_buffer, &result) != 0) + abort(); + ++count; + } while (result != NULL); + fprintf(stderr, "read %d entries\n", count); + closedir(d); + // CHECK: test1: reading the {{.*}} directory... + // CHECK-NOT: stack-buffer-overflow + // CHECK: read {{.*}} entries + + // Ensure the readdir64_r interceptor doesn't have the bug either. + fputs("test2: reading the " TEMP_DIR " directory...\n", stderr); + d = opendir(TEMP_DIR); + struct dirent64 *result64; + memset(entry_buffer, 0xab, sizeof(entry_buffer)); + count = 0; + do { + // Stamp the entry struct to try to trick the interceptor. + ((struct dirent64 *)entry_buffer)->d_reclen = 9999; + if (readdir64_r(d, (struct dirent64 *)entry_buffer, &result64) != 0) + abort(); + ++count; + } while (result64 != NULL); + fprintf(stderr, "read %d entries\n", count); + closedir(d); + // CHECK: test2: reading the {{.*}} directory... + // CHECK-NOT: stack-buffer-overflow + // CHECK: read {{.*}} entries +} diff --git a/lib/asan/lit_tests/TestCases/Linux/interception_test.cc b/lib/asan/lit_tests/TestCases/Linux/interception_test.cc new file mode 100644 index 000000000000..2b3316d7dc8a --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/interception_test.cc @@ -0,0 +1,22 @@ +// ASan interceptor can be accessed with __interceptor_ prefix. + +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s +#include <stdlib.h> +#include <stdio.h> + +extern "C" long __interceptor_strtol(const char *nptr, char **endptr, int base); +extern "C" long strtol(const char *nptr, char **endptr, int base) { + fprintf(stderr, "my_strtol_interceptor\n"); + return __interceptor_strtol(nptr, endptr, base); +} + +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return (int)strtol(x, 0, 10); + // CHECK: my_strtol_interceptor + // CHECK: heap-use-after-free +} diff --git a/lib/asan/lit_tests/Linux/interface_symbols_linux.c b/lib/asan/lit_tests/TestCases/Linux/interface_symbols_linux.c index 4134c8744043..d6ceda7af8b6 100644 --- a/lib/asan/lit_tests/Linux/interface_symbols_linux.c +++ b/lib/asan/lit_tests/TestCases/Linux/interface_symbols_linux.c @@ -1,14 +1,15 @@ // Check the presense of interface symbols in compiled file. -// RUN: %clang -fsanitize=address -O2 %s -o %t.exe +// RUN: %clang_asan -O2 %s -o %t.exe // RUN: nm -D %t.exe | grep " T " | sed "s/.* T //" \ // RUN: | grep "__asan_" | sed "s/___asan_/__asan_/" \ // RUN: | grep -v "__asan_malloc_hook" \ // RUN: | grep -v "__asan_free_hook" \ // RUN: | grep -v "__asan_symbolize" \ // RUN: | grep -v "__asan_default_options" \ +// RUN: | grep -v "__asan_stack_" \ // RUN: | grep -v "__asan_on_error" > %t.symbols -// RUN: cat %p/../../asan_interface_internal.h \ +// RUN: cat %p/../../../asan_interface_internal.h \ // RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \ // RUN: | grep -v "OPTIONAL" \ // RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \ diff --git a/lib/asan/lit_tests/Linux/lit.local.cfg b/lib/asan/lit_tests/TestCases/Linux/lit.local.cfg index 57271b8078a4..57271b8078a4 100644 --- a/lib/asan/lit_tests/Linux/lit.local.cfg +++ b/lib/asan/lit_tests/TestCases/Linux/lit.local.cfg diff --git a/lib/asan/lit_tests/Linux/malloc-in-qsort.cc b/lib/asan/lit_tests/TestCases/Linux/malloc-in-qsort.cc index ee2e81f0d2ab..3251b35e143c 100644 --- a/lib/asan/lit_tests/Linux/malloc-in-qsort.cc +++ b/lib/asan/lit_tests/TestCases/Linux/malloc-in-qsort.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_asan -m64 -O2 %s -o %t -// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=1 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-FAST -// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-SLOW +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=1 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST +// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW // Test how well we unwind in presence of qsort in the stack // (i.e. if we can unwind through a function compiled w/o frame pointers). @@ -9,6 +9,8 @@ // Fast unwinder is only avaliable on x86_64 and i386. // REQUIRES: x86_64-supported-target +// REQUIRES: compiler-rt-optimized + #include <stdlib.h> #include <stdio.h> diff --git a/lib/asan/lit_tests/Linux/malloc_delete_mismatch.cc b/lib/asan/lit_tests/TestCases/Linux/malloc_delete_mismatch.cc index f34b33a38fb3..7010eb2de2e7 100644 --- a/lib/asan/lit_tests/Linux/malloc_delete_mismatch.cc +++ b/lib/asan/lit_tests/TestCases/Linux/malloc_delete_mismatch.cc @@ -2,11 +2,16 @@ // is set. // RUN: %clangxx_asan -g %s -o %t 2>&1 -// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1 %t 2>&1 | \ -// RUN: %symbolize | FileCheck %s + +// Find error and provide malloc context. +// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1 not %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALLOC-STACK // No error here. // RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=0 %t + +// Also works if no malloc context is available. +// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=0 not %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=1 not %t 2>&1 | FileCheck %s #include <stdlib.h> static volatile char *x; @@ -21,6 +26,6 @@ int main() { // CHECK: #{{.*}}main // CHECK: is located 0 bytes inside of 10-byte region // CHECK-NEXT: allocated by thread T0 here: -// CHECK-NEXT: #0{{.*}}malloc -// CHECK: #{{.*}}main +// ALLOC-STACK-NEXT: #0{{.*}}malloc +// ALLOC-STACK: #{{.*}}main // CHECK: HINT: {{.*}} you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0 diff --git a/lib/asan/lit_tests/Linux/overflow-in-qsort.cc b/lib/asan/lit_tests/TestCases/Linux/overflow-in-qsort.cc index 8bc43ca0a5c3..139977261ec9 100644 --- a/lib/asan/lit_tests/Linux/overflow-in-qsort.cc +++ b/lib/asan/lit_tests/TestCases/Linux/overflow-in-qsort.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_asan -m64 -O2 %s -o %t -// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=1 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-FAST -// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=0 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-SLOW +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=1 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST +// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=0 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW // Test how well we unwind in presence of qsort in the stack // (i.e. if we can unwind through a function compiled w/o frame pointers). diff --git a/lib/asan/lit_tests/Linux/preinit_test.cc b/lib/asan/lit_tests/TestCases/Linux/preinit_test.cc index 28e509472c0c..28e509472c0c 100644 --- a/lib/asan/lit_tests/Linux/preinit_test.cc +++ b/lib/asan/lit_tests/TestCases/Linux/preinit_test.cc diff --git a/lib/asan/lit_tests/TestCases/Linux/ptrace.cc b/lib/asan/lit_tests/TestCases/Linux/ptrace.cc new file mode 100644 index 000000000000..8831b81efa96 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/ptrace.cc @@ -0,0 +1,52 @@ +// RUN: %clangxx_asan -O0 %s -o %t && %t +// RUN: %clangxx_asan -DPOSITIVE -O0 %s -o %t && not %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdio.h> +#include <sys/ptrace.h> +#include <sys/types.h> +#include <sys/user.h> +#include <sys/wait.h> +#include <unistd.h> + +int main(void) { + pid_t pid; + pid = fork(); + if (pid == 0) { // child + ptrace(PTRACE_TRACEME, 0, NULL, NULL); + execl("/bin/true", "true", NULL); + } else { + wait(NULL); + user_regs_struct regs; + int res; + user_regs_struct * volatile pregs = ®s; +#ifdef POSITIVE + ++pregs; +#endif + res = ptrace(PTRACE_GETREGS, pid, NULL, pregs); + // CHECK: AddressSanitizer: stack-buffer-overflow + // CHECK: {{.*ptrace.cc:}}[[@LINE-2]] + assert(!res); +#if __WORDSIZE == 64 + printf("%zx\n", regs.rip); +#else + printf("%lx\n", regs.eip); +#endif + + user_fpregs_struct fpregs; + res = ptrace(PTRACE_GETFPREGS, pid, NULL, &fpregs); + assert(!res); + printf("%lx\n", (unsigned long)fpregs.cwd); + +#if __WORDSIZE == 32 + user_fpxregs_struct fpxregs; + res = ptrace(PTRACE_GETFPXREGS, pid, NULL, &fpxregs); + assert(!res); + printf("%lx\n", (unsigned long)fpxregs.mxcsr); +#endif + + ptrace(PTRACE_CONT, pid, NULL, NULL); + wait(NULL); + } + return 0; +} diff --git a/lib/asan/lit_tests/Linux/rlimit_mmap_test.cc b/lib/asan/lit_tests/TestCases/Linux/rlimit_mmap_test.cc index 86794756c76f..0d1d4baa7671 100644 --- a/lib/asan/lit_tests/Linux/rlimit_mmap_test.cc +++ b/lib/asan/lit_tests/TestCases/Linux/rlimit_mmap_test.cc @@ -1,5 +1,5 @@ // Check that we properly report mmap failure. -// RUN: %clangxx_asan %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan %s -o %t && not %t 2>&1 | FileCheck %s #include <stdlib.h> #include <assert.h> #include <sys/time.h> diff --git a/lib/asan/lit_tests/Linux/swapcontext_test.cc b/lib/asan/lit_tests/TestCases/Linux/swapcontext_test.cc index 47a8d9891f51..6cbb69a35321 100644 --- a/lib/asan/lit_tests/Linux/swapcontext_test.cc +++ b/lib/asan/lit_tests/TestCases/Linux/swapcontext_test.cc @@ -1,13 +1,9 @@ // Check that ASan plays well with easy cases of makecontext/swapcontext. -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && %t 2>&1 | FileCheck %s // // This test is too sublte to try on non-x86 arch for now. // REQUIRES: x86_64-supported-target,i386-supported-target diff --git a/lib/asan/lit_tests/Linux/syscalls.cc b/lib/asan/lit_tests/TestCases/Linux/syscalls.cc index b2edcfb92375..4bcbe446113e 100644 --- a/lib/asan/lit_tests/Linux/syscalls.cc +++ b/lib/asan/lit_tests/TestCases/Linux/syscalls.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s #include <assert.h> #include <errno.h> @@ -17,6 +17,6 @@ int main(int argc, char *argv[]) { __sanitizer_syscall_pre_recvmsg(0, buf - 1, 0); // CHECK: AddressSanitizer: stack-buffer-{{.*}}erflow // CHECK: READ of size {{.*}} at {{.*}} thread T0 - // CHECK: #0 {{.*}} in __sanitizer_syscall_pre_recvmsg + // CHECK: #0 {{.*}} in __sanitizer_syscall{{.*}}recvmsg return 0; } diff --git a/lib/asan/lit_tests/Linux/time_null_regtest.cc b/lib/asan/lit_tests/TestCases/Linux/time_null_regtest.cc index 975bca3d105a..566409be6a19 100644 --- a/lib/asan/lit_tests/Linux/time_null_regtest.cc +++ b/lib/asan/lit_tests/TestCases/Linux/time_null_regtest.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -m64 -O0 %s -fsanitize-address-zero-base-shadow -pie -o %t && %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -fsanitize-address-zero-base-shadow -pie -o %t && %t 2>&1 | FileCheck %s // Zero-base shadow only works on x86_64 and i386. // REQUIRES: x86_64-supported-target diff --git a/lib/asan/lit_tests/TestCases/Linux/tsd_dtor_leak.cc b/lib/asan/lit_tests/TestCases/Linux/tsd_dtor_leak.cc new file mode 100644 index 000000000000..a1d89ee437d4 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/tsd_dtor_leak.cc @@ -0,0 +1,39 @@ +// Regression test for a leak in tsd: +// https://code.google.com/p/address-sanitizer/issues/detail?id=233 +// RUN: %clangxx_asan -O1 %s -o %t +// RUN: ASAN_OPTIONS=quarantine_size=1 %t +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> + +extern "C" size_t __asan_get_heap_size(); +static pthread_key_t tsd_key; + +void *Thread(void *) { + pthread_setspecific(tsd_key, malloc(10)); + return 0; +} + +static volatile void *v; + +void Dtor(void *tsd) { + v = malloc(10000); + free(tsd); + free((void*)v); // The bug was that this was leaking. +} + +int main() { + assert(0 == pthread_key_create(&tsd_key, Dtor)); + size_t old_heap_size = 0; + for (int i = 0; i < 10; i++) { + pthread_t t; + pthread_create(&t, 0, Thread, 0); + pthread_join(t, 0); + size_t new_heap_size = __asan_get_heap_size(); + fprintf(stderr, "heap size: new: %zd old: %zd\n", new_heap_size, old_heap_size); + if (old_heap_size) + assert(old_heap_size == new_heap_size); + old_heap_size = new_heap_size; + } +} diff --git a/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc b/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc new file mode 100644 index 000000000000..9663859dfefd --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/uar_signals.cc @@ -0,0 +1,70 @@ +// This test shows that the current implementation of use-after-return is +// not signal-safe. +// RUN: %clangxx_asan -O1 %s -o %t -lpthread && %t +// RUN: %clangxx_asan -O1 %s -o %t -lpthread && %t +#include <signal.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/time.h> +#include <pthread.h> + +int *g; +int n_signals; + +typedef void (*Sigaction)(int, siginfo_t *, void *); + +void SignalHandler(int, siginfo_t*, void*) { + int local; + g = &local; + n_signals++; + // printf("s: %p\n", &local); +} + +static void EnableSigprof(Sigaction SignalHandler) { + struct sigaction sa; + sa.sa_sigaction = SignalHandler; + sa.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGPROF, &sa, NULL) != 0) { + perror("sigaction"); + abort(); + } + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + if (setitimer(ITIMER_PROF, &timer, 0) != 0) { + perror("setitimer"); + abort(); + } +} + +void RecursiveFunction(int depth) { + if (depth == 0) return; + int local; + g = &local; + // printf("r: %p\n", &local); + // printf("[%2d] n_signals: %d\n", depth, n_signals); + RecursiveFunction(depth - 1); + RecursiveFunction(depth - 1); +} + +void *Thread(void *) { + RecursiveFunction(18); + return NULL; +} + +int main(int argc, char **argv) { + EnableSigprof(SignalHandler); + + for (int i = 0; i < 4; i++) { + fprintf(stderr, "."); + const int kNumThread = sizeof(void*) == 8 ? 16 : 8; + pthread_t t[kNumThread]; + for (int i = 0; i < kNumThread; i++) + pthread_create(&t[i], 0, Thread, 0); + for (int i = 0; i < kNumThread; i++) + pthread_join(t[i], 0); + } + fprintf(stderr, "\n"); +} diff --git a/lib/asan/lit_tests/TestCases/Linux/unpoison_tls.cc b/lib/asan/lit_tests/TestCases/Linux/unpoison_tls.cc new file mode 100644 index 000000000000..d67c4f954e43 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/unpoison_tls.cc @@ -0,0 +1,35 @@ +// Test that TLS is unpoisoned on thread death. +// REQUIRES: x86_64-supported-target,i386-supported-target + +// RUN: %clangxx_asan -O1 %s -o %t && %t 2>&1 + +#include <assert.h> +#include <pthread.h> +#include <stdio.h> + +#include <sanitizer/asan_interface.h> + +__thread int64_t tls_var[2]; + +volatile int64_t *p_tls_var; + +void *first(void *arg) { + ASAN_POISON_MEMORY_REGION(&tls_var, sizeof(tls_var)); + p_tls_var = tls_var; + return 0; +} + +void *second(void *arg) { + assert(tls_var == p_tls_var); + *p_tls_var = 1; + return 0; +} + +int main(int argc, char *argv[]) { + pthread_t p; + assert(0 == pthread_create(&p, 0, first, 0)); + assert(0 == pthread_join(p, 0)); + assert(0 == pthread_create(&p, 0, second, 0)); + assert(0 == pthread_join(p, 0)); + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/Linux/zero-base-shadow32.cc b/lib/asan/lit_tests/TestCases/Linux/zero-base-shadow32.cc new file mode 100644 index 000000000000..e6bcc5597471 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/zero-base-shadow32.cc @@ -0,0 +1,24 @@ +// RUN: %clangxx_asan -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t +// RUN: not %t 2>&1 | FileCheck %s + +// Zero-base shadow only works on x86_64 and i386. +// REQUIRES: i386-supported-target, asan-32-bits + +#include <string.h> +int main(int argc, char **argv) { + char x[10]; + memset(x, 0, 10); + int res = x[argc * 10]; // BOOOM + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*zero-base-shadow32.cc:}}[[@LINE-2]] + // CHECK: {{Address 0x.* is .* frame}} + // CHECK: main + + // Check that shadow for stack memory occupies lower part of address space. + // CHECK: =>0x1 + return res; +} diff --git a/lib/asan/lit_tests/TestCases/Linux/zero-base-shadow64.cc b/lib/asan/lit_tests/TestCases/Linux/zero-base-shadow64.cc new file mode 100644 index 000000000000..1db725c95752 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Linux/zero-base-shadow64.cc @@ -0,0 +1,24 @@ +// RUN: %clangxx_asan -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t +// RUN: not %t 2>&1 | FileCheck %s + +// Zero-base shadow only works on x86_64 and i386. +// REQUIRES: x86_64-supported-target, asan-64-bits + +#include <string.h> +int main(int argc, char **argv) { + char x[10]; + memset(x, 0, 10); + int res = x[argc * 10]; // BOOOM + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*zero-base-shadow64.cc:}}[[@LINE-2]] + // CHECK: {{Address 0x.* is .* frame}} + // CHECK: main + + // Check that shadow for stack memory occupies lower part of address space. + // CHECK: =>0x0f + return res; +} diff --git a/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc b/lib/asan/lit_tests/TestCases/SharedLibs/darwin-dummy-shared-lib-so.cc index 5d939991476e..5d939991476e 100644 --- a/lib/asan/lit_tests/SharedLibs/darwin-dummy-shared-lib-so.cc +++ b/lib/asan/lit_tests/TestCases/SharedLibs/darwin-dummy-shared-lib-so.cc diff --git a/lib/asan/lit_tests/SharedLibs/dlclose-test-so.cc b/lib/asan/lit_tests/TestCases/SharedLibs/dlclose-test-so.cc index 73e00507358a..73e00507358a 100644 --- a/lib/asan/lit_tests/SharedLibs/dlclose-test-so.cc +++ b/lib/asan/lit_tests/TestCases/SharedLibs/dlclose-test-so.cc diff --git a/lib/asan/lit_tests/SharedLibs/init-order-dlopen-so.cc b/lib/asan/lit_tests/TestCases/SharedLibs/init-order-dlopen-so.cc index 20ef2d8a00bb..dc097a520d03 100644 --- a/lib/asan/lit_tests/SharedLibs/init-order-dlopen-so.cc +++ b/lib/asan/lit_tests/TestCases/SharedLibs/init-order-dlopen-so.cc @@ -1,7 +1,7 @@ #include <stdio.h> #include <unistd.h> -void inc_global(); +extern "C" void inc_global(); int slow_init() { sleep(1); diff --git a/lib/asan/lit_tests/SharedLibs/lit.local.cfg b/lib/asan/lit_tests/TestCases/SharedLibs/lit.local.cfg index b3677c17a0f2..b3677c17a0f2 100644 --- a/lib/asan/lit_tests/SharedLibs/lit.local.cfg +++ b/lib/asan/lit_tests/TestCases/SharedLibs/lit.local.cfg diff --git a/lib/asan/lit_tests/SharedLibs/shared-lib-test-so.cc b/lib/asan/lit_tests/TestCases/SharedLibs/shared-lib-test-so.cc index 686a24578082..6ef565ce47b3 100644 --- a/lib/asan/lit_tests/SharedLibs/shared-lib-test-so.cc +++ b/lib/asan/lit_tests/TestCases/SharedLibs/shared-lib-test-so.cc @@ -19,3 +19,8 @@ extern "C" void inc(int index) { GLOB[index]++; } + +extern "C" +void inc2(int *a, int index) { + a[index]++; +} diff --git a/lib/asan/lit_tests/TestCases/allocator_returns_null.cc b/lib/asan/lit_tests/TestCases/allocator_returns_null.cc new file mode 100644 index 000000000000..595c9e252f86 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/allocator_returns_null.cc @@ -0,0 +1,81 @@ +// Test the behavior of malloc/calloc/realloc when the allocation size is huge. +// By default (allocator_may_return_null=0) the process should crash. +// With allocator_may_return_null=1 the allocator should return 0. +// +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mNULL +// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH +// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cNULL +// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH +// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coNULL +// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH +// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rNULL +// RUN: ASAN_OPTIONS=allocator_may_return_null=0 not %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH +// RUN: ASAN_OPTIONS=allocator_may_return_null=1 %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrNULL + +#include <limits.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <assert.h> +#include <limits> +int main(int argc, char **argv) { + volatile size_t size = std::numeric_limits<size_t>::max() - 10000; + assert(argc == 2); + char *x = 0; + if (!strcmp(argv[1], "malloc")) { + fprintf(stderr, "malloc:\n"); + x = (char*)malloc(size); + } + if (!strcmp(argv[1], "calloc")) { + fprintf(stderr, "calloc:\n"); + x = (char*)calloc(size / 4, 4); + } + + if (!strcmp(argv[1], "calloc-overflow")) { + fprintf(stderr, "calloc-overflow:\n"); + volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max(); + size_t kArraySize = 4096; + volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; + x = (char*)calloc(kArraySize, kArraySize2); + } + + if (!strcmp(argv[1], "realloc")) { + fprintf(stderr, "realloc:\n"); + x = (char*)realloc(0, size); + } + if (!strcmp(argv[1], "realloc-after-malloc")) { + fprintf(stderr, "realloc-after-malloc:\n"); + char *t = (char*)malloc(100); + *t = 42; + x = (char*)realloc(t, size); + assert(*t == 42); + } + // The NULL pointer is printed differently on different systems, while (long)0 + // is always the same. + fprintf(stderr, "x: %lx\n", (long)x); + return x != 0; +} +// CHECK-mCRASH: malloc: +// CHECK-mCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-cCRASH: calloc: +// CHECK-cCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-coCRASH: calloc-overflow: +// CHECK-coCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-rCRASH: realloc: +// CHECK-rCRASH: AddressSanitizer's allocator is terminating the process +// CHECK-mrCRASH: realloc-after-malloc: +// CHECK-mrCRASH: AddressSanitizer's allocator is terminating the process + +// CHECK-mNULL: malloc: +// CHECK-mNULL: x: 0 +// CHECK-cNULL: calloc: +// CHECK-cNULL: x: 0 +// CHECK-coNULL: calloc-overflow: +// CHECK-coNULL: x: 0 +// CHECK-rNULL: realloc: +// CHECK-rNULL: x: 0 +// CHECK-mrNULL: realloc-after-malloc: +// CHECK-mrNULL: x: 0 diff --git a/lib/asan/lit_tests/allow_user_segv.cc b/lib/asan/lit_tests/TestCases/allow_user_segv.cc index f8aed0d4ca80..55cf6044e7a0 100644 --- a/lib/asan/lit_tests/allow_user_segv.cc +++ b/lib/asan/lit_tests/TestCases/allow_user_segv.cc @@ -1,10 +1,8 @@ // Regression test for // https://code.google.com/p/address-sanitizer/issues/detail?id=180 -// RUN: %clangxx_asan -m64 -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true not %t 2>&1 | FileCheck %s #include <signal.h> #include <stdio.h> diff --git a/lib/asan/lit_tests/TestCases/asan-symbolize-sanity-test.cc b/lib/asan/lit_tests/TestCases/asan-symbolize-sanity-test.cc new file mode 100644 index 000000000000..0efe245bb6b5 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/asan-symbolize-sanity-test.cc @@ -0,0 +1,39 @@ +// Check that asan_symbolize.py script works (for binaries, ASan RTL and +// shared object files. + +// RUN: %clangxx_asan -O0 %p/SharedLibs/shared-lib-test-so.cc -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: ASAN_SYMBOLIZER_PATH= not %t 2>&1 | %asan_symbolize | FileCheck %s +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +#include <string> + +using std::string; + +typedef void (fun_t)(int*, int); + +int main(int argc, char *argv[]) { + string path = string(argv[0]) + "-so.so"; + printf("opening %s ... \n", path.c_str()); + void *lib = dlopen(path.c_str(), RTLD_NOW); + if (!lib) { + printf("error in dlopen(): %s\n", dlerror()); + return 1; + } + fun_t *inc2 = (fun_t*)dlsym(lib, "inc2"); + if (!inc2) return 1; + printf("ok\n"); + int *array = (int*)malloc(40); + inc2(array, 1); + inc2(array, -1); // BOOM + // CHECK: ERROR: AddressSanitizer: heap-buffer-overflow + // CHECK: READ of size 4 at 0x{{.*}} + // CHECK: #0 {{.*}} in inc2 {{.*}}shared-lib-test-so.cc:25 + // CHECK: #1 {{.*}} in main {{.*}}asan-symbolize-sanity-test.cc:[[@LINE-4]] + // CHECK: allocated by thread T{{.*}} here: + // CHECK: #{{.*}} in {{(wrap_|__interceptor_)?}}malloc + // CHECK: #{{.*}} in main {{.*}}asan-symbolize-sanity-test.cc:[[@LINE-9]] + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/assign_large_valloc_to_global.cc b/lib/asan/lit_tests/TestCases/assign_large_valloc_to_global.cc new file mode 100644 index 000000000000..b0a501576945 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/assign_large_valloc_to_global.cc @@ -0,0 +1,8 @@ +// Make sure we don't report a leak nor hang. +// RUN: %clangxx_asan -O3 %s -o %t && %t +#include <stdlib.h> +#ifndef __APPLE__ +#include <malloc.h> +#endif // __APPLE__ +int *p = (int*)valloc(1 << 20); +int main() { } diff --git a/lib/asan/lit_tests/TestCases/atexit_stats.cc b/lib/asan/lit_tests/TestCases/atexit_stats.cc new file mode 100644 index 000000000000..e3b1269d25cc --- /dev/null +++ b/lib/asan/lit_tests/TestCases/atexit_stats.cc @@ -0,0 +1,13 @@ +// Make sure we report atexit stats. +// RUN: %clangxx_asan -O3 %s -o %t +// RUN: ASAN_OPTIONS=atexit=1:print_stats=1 %t 2>&1 | FileCheck %s +#include <stdlib.h> +#if !defined(__APPLE__) +#include <malloc.h> +#endif +int *p1 = (int*)malloc(900); +int *p2 = (int*)malloc(90000); +int *p3 = (int*)malloc(9000000); +int main() { } + +// CHECK: AddressSanitizer exit stats: diff --git a/lib/asan/lit_tests/blacklist.cc b/lib/asan/lit_tests/TestCases/blacklist.cc index 6cfc1500c503..46625ee7bdb5 100644 --- a/lib/asan/lit_tests/blacklist.cc +++ b/lib/asan/lit_tests/TestCases/blacklist.cc @@ -3,25 +3,19 @@ // RUN: echo "fun:*brokenFunction*" > %tmp // RUN: echo "global:*badGlobal*" >> %tmp // RUN: echo "src:*blacklist-extra.cc" >> %tmp -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m64 -O0 %s -o %t \ +// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -O0 %s -o %t \ // RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m64 -O1 %s -o %t \ +// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -O1 %s -o %t \ // RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m64 -O2 %s -o %t \ +// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -O2 %s -o %t \ // RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m64 -O3 %s -o %t \ -// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m32 -O0 %s -o %t \ -// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m32 -O1 %s -o %t \ -// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m32 -O2 %s -o %t \ -// RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -m32 -O3 %s -o %t \ +// RUN: %clangxx_asan -fsanitize-blacklist=%tmp -O3 %s -o %t \ // RUN: %p/Helpers/blacklist-extra.cc && %t 2>&1 -// badGlobal is accessed improperly, but we blacklisted it. -int badGlobal; +// badGlobal is accessed improperly, but we blacklisted it. Align +// it to make sure memory past the end of badGlobal will be in +// the same page. +__attribute__((aligned(16))) int badGlobal; int readBadGlobal() { return (&badGlobal)[1]; } diff --git a/lib/asan/lit_tests/TestCases/contiguous_container.cc b/lib/asan/lit_tests/TestCases/contiguous_container.cc new file mode 100644 index 000000000000..aa97592c7bb9 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/contiguous_container.cc @@ -0,0 +1,47 @@ +// RUN: %clangxx_asan -O %s -o %t && %t +// +// Test __sanitizer_annotate_contiguous_container. + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> + +extern "C" { +void __sanitizer_annotate_contiguous_container(void *beg, void *end, + void *old_mid, void *new_mid); +bool __asan_address_is_poisoned(void *addr); +} // extern "C" + +void TestContainer(size_t capacity) { + char *beg = new char[capacity]; + char *end = beg + capacity; + char *mid = beg + capacity; + char *old_mid = 0; + unsigned seed = 0; + + for (int i = 0; i < 10000; i++) { + size_t size = rand_r(&seed) % (capacity + 1); + assert(size <= capacity); + old_mid = mid; + mid = beg + size; + __sanitizer_annotate_contiguous_container(beg, end, old_mid, mid); + + for (size_t idx = 0; idx < size; idx++) + assert(!__asan_address_is_poisoned(beg + idx)); + for (size_t idx = size; idx < capacity; idx++) + assert(__asan_address_is_poisoned(beg + idx)); + } + + // Don't forget to unpoison the whole thing before destroing/reallocating. + __sanitizer_annotate_contiguous_container(beg, end, mid, end); + for (size_t idx = 0; idx < capacity; idx++) + assert(!__asan_address_is_poisoned(beg + idx)); + delete[] beg; +} + +int main(int argc, char **argv) { + int n = argc == 1 ? 128 : atoi(argv[1]); + for (int i = 0; i <= n; i++) + TestContainer(i); +} diff --git a/lib/asan/lit_tests/TestCases/current_allocated_bytes.cc b/lib/asan/lit_tests/TestCases/current_allocated_bytes.cc new file mode 100644 index 000000000000..669cf150bdfb --- /dev/null +++ b/lib/asan/lit_tests/TestCases/current_allocated_bytes.cc @@ -0,0 +1,43 @@ +// RUN: %clangxx_asan -O0 %s -o %t && %t +// RUN: %clangxx_asan -O2 %s -o %t && %t + +#include <assert.h> +#include <pthread.h> +#include <sanitizer/asan_interface.h> +#include <stdio.h> +#include <stdlib.h> + +const size_t kLargeAlloc = 1UL << 20; + +void* allocate(void *arg) { + volatile void *ptr = malloc(kLargeAlloc); + free((void*)ptr); + return 0; +} + +void* check_stats(void *arg) { + assert(__asan_get_current_allocated_bytes() > 0); + return 0; +} + +int main() { + size_t used_mem = __asan_get_current_allocated_bytes(); + printf("Before: %zu\n", used_mem); + const int kNumIterations = 1000; + for (int iter = 0; iter < kNumIterations; iter++) { + pthread_t thr[4]; + for (int j = 0; j < 4; j++) { + assert(0 == + pthread_create(&thr[j], 0, (j < 2) ? allocate : check_stats, 0)); + } + for (int j = 0; j < 4; j++) + assert(0 == pthread_join(thr[j], 0)); + used_mem = __asan_get_current_allocated_bytes(); + if (used_mem > kLargeAlloc) { + printf("After iteration %d: %zu\n", iter, used_mem); + return 1; + } + } + printf("Success after %d iterations\n", kNumIterations); + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/deep_call_stack.cc b/lib/asan/lit_tests/TestCases/deep_call_stack.cc new file mode 100644 index 000000000000..e24704b9019e --- /dev/null +++ b/lib/asan/lit_tests/TestCases/deep_call_stack.cc @@ -0,0 +1,25 @@ +// Check that UAR mode can handle very deep recusrion. +// export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: %clangxx_asan -O2 %s -o %t && \ +// RUN: %t 2>&1 | FileCheck %s +// Also check that use_sigaltstack+verbosity doesn't crash. +// RUN: ASAN_OPTIONS=verbosity=1:use_sigaltstack=1 %t | FileCheck %s +#include <stdio.h> + +__attribute__((noinline)) +void RecursiveFunc(int depth, int *ptr) { + if ((depth % 1000) == 0) + printf("[%05d] ptr: %p\n", depth, ptr); + if (depth == 0) + return; + int local; + RecursiveFunc(depth - 1, &local); +} + +int main(int argc, char **argv) { + RecursiveFunc(40000, 0); + return 0; +} +// CHECK: [40000] ptr: +// CHECK: [20000] ptr: +// CHECK: [00000] ptr diff --git a/lib/asan/lit_tests/deep_stack_uaf.cc b/lib/asan/lit_tests/TestCases/deep_stack_uaf.cc index 7b32798fefcc..920411c4ac52 100644 --- a/lib/asan/lit_tests/deep_stack_uaf.cc +++ b/lib/asan/lit_tests/TestCases/deep_stack_uaf.cc @@ -1,12 +1,7 @@ // Check that we can store lots of stack frames if asked to. -// RUN: %clangxx_asan -m64 -O0 %s -o %t 2>&1 -// RUN: ASAN_OPTIONS=malloc_context_size=120:redzone=512 %t 2>&1 | \ -// RUN: %symbolize | FileCheck %s - -// RUN: %clangxx_asan -m32 -O0 %s -o %t 2>&1 -// RUN: ASAN_OPTIONS=malloc_context_size=120:redzone=512 %t 2>&1 | \ -// RUN: %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t 2>&1 +// RUN: ASAN_OPTIONS=malloc_context_size=120:redzone=512 not %t 2>&1 | FileCheck %s #include <stdlib.h> #include <stdio.h> diff --git a/lib/asan/lit_tests/TestCases/deep_tail_call.cc b/lib/asan/lit_tests/TestCases/deep_tail_call.cc new file mode 100644 index 000000000000..2e7aa8e0208f --- /dev/null +++ b/lib/asan/lit_tests/TestCases/deep_tail_call.cc @@ -0,0 +1,20 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// CHECK: AddressSanitizer: global-buffer-overflow +int global[10]; +// CHECK: {{#0.*call4}} +void __attribute__((noinline)) call4(int i) { global[i+10]++; } +// CHECK: {{#1.*call3}} +void __attribute__((noinline)) call3(int i) { call4(i); } +// CHECK: {{#2.*call2}} +void __attribute__((noinline)) call2(int i) { call3(i); } +// CHECK: {{#3.*call1}} +void __attribute__((noinline)) call1(int i) { call2(i); } +// CHECK: {{#4.*main}} +int main(int argc, char **argv) { + call1(argc); + return global[0]; +} diff --git a/lib/asan/lit_tests/deep_thread_stack.cc b/lib/asan/lit_tests/TestCases/deep_thread_stack.cc index 781508d61616..92e0d66c82eb 100644 --- a/lib/asan/lit_tests/deep_thread_stack.cc +++ b/lib/asan/lit_tests/TestCases/deep_thread_stack.cc @@ -1,11 +1,7 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s #include <pthread.h> diff --git a/lib/asan/lit_tests/default_blacklist.cc b/lib/asan/lit_tests/TestCases/default_blacklist.cc index 25a1ae1752b0..25a1ae1752b0 100644 --- a/lib/asan/lit_tests/default_blacklist.cc +++ b/lib/asan/lit_tests/TestCases/default_blacklist.cc diff --git a/lib/asan/lit_tests/default_options.cc b/lib/asan/lit_tests/TestCases/default_options.cc index 84b80557b852..84b80557b852 100644 --- a/lib/asan/lit_tests/default_options.cc +++ b/lib/asan/lit_tests/TestCases/default_options.cc diff --git a/lib/asan/lit_tests/dlclose-test.cc b/lib/asan/lit_tests/TestCases/dlclose-test.cc index b15895bf3579..03ed16016116 100644 --- a/lib/asan/lit_tests/dlclose-test.cc +++ b/lib/asan/lit_tests/TestCases/dlclose-test.cc @@ -14,30 +14,18 @@ // It works on i368/x86_64 Linux, but not necessary anywhere else. // REQUIRES: x86_64-supported-target,i386-supported-target -// RUN: %clangxx_asan -m64 -O0 %p/SharedLibs/dlclose-test-so.cc \ +// RUN: %clangxx_asan -O0 %p/SharedLibs/dlclose-test-so.cc \ // RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %p/SharedLibs/dlclose-test-so.cc \ +// RUN: %clangxx_asan -O0 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %p/SharedLibs/dlclose-test-so.cc \ // RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %p/SharedLibs/dlclose-test-so.cc \ +// RUN: %clangxx_asan -O1 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %p/SharedLibs/dlclose-test-so.cc \ // RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %p/SharedLibs/dlclose-test-so.cc \ +// RUN: %clangxx_asan -O2 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %p/SharedLibs/dlclose-test-so.cc \ // RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %p/SharedLibs/dlclose-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %p/SharedLibs/dlclose-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %p/SharedLibs/dlclose-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %p/SharedLibs/dlclose-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && %t 2>&1 | FileCheck %s #include <assert.h> #include <dlfcn.h> diff --git a/lib/asan/lit_tests/TestCases/double-free.cc b/lib/asan/lit_tests/TestCases/double-free.cc new file mode 100644 index 000000000000..6bfd4fa2c7e5 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/double-free.cc @@ -0,0 +1,25 @@ +// RUN: %clangxx_asan -O0 %s -o %t 2>&1 +// RUN: not %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX + +// Also works if no malloc context is available. +// RUN: ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %t 2>&1 | FileCheck %s + +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + char *x = (char*)malloc(10 * sizeof(char)); + memset(x, 0, 10); + int res = x[argc]; + free(x); + free(x + argc - 1); // BOOM + // CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0 + // CHECK: #0 0x{{.*}} in {{.*}}free + // CHECK: #1 0x{{.*}} in main {{.*}}double-free.cc:[[@LINE-3]] + // CHECK: freed by thread T0 here: + // MALLOC-CTX: #0 0x{{.*}} in {{.*}}free + // MALLOC-CTX: #1 0x{{.*}} in main {{.*}}double-free.cc:[[@LINE-7]] + // CHECK: allocated by thread T0 here: + // MALLOC-CTX: double-free.cc:[[@LINE-12]] + return res; +} diff --git a/lib/asan/lit_tests/force_inline_opt0.cc b/lib/asan/lit_tests/TestCases/force_inline_opt0.cc index 955ce38156fb..775a66dfe2fe 100644 --- a/lib/asan/lit_tests/force_inline_opt0.cc +++ b/lib/asan/lit_tests/TestCases/force_inline_opt0.cc @@ -1,7 +1,7 @@ // This test checks that we are no instrumenting a memory access twice // (before and after inlining) -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t +// RUN: %clangxx_asan -O1 %s -o %t && %t +// RUN: %clangxx_asan -O0 %s -o %t && %t __attribute__((always_inline)) void foo(int *x) { *x = 0; diff --git a/lib/asan/lit_tests/TestCases/free_hook_realloc.cc b/lib/asan/lit_tests/TestCases/free_hook_realloc.cc new file mode 100644 index 000000000000..7a71964b0032 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/free_hook_realloc.cc @@ -0,0 +1,32 @@ +// Check that free hook doesn't conflict with Realloc. +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: %t 2>&1 | FileCheck %s +#include <stdlib.h> +#include <unistd.h> + +static void *glob_ptr; + +extern "C" { +void __asan_free_hook(void *ptr) { + if (ptr == glob_ptr) { + *(int*)ptr = 0; + write(1, "FreeHook\n", sizeof("FreeHook\n")); + } +} +} + +int main() { + int *x = (int*)malloc(100); + x[0] = 42; + glob_ptr = x; + int *y = (int*)realloc(x, 200); + // Verify that free hook was called and didn't spoil the memory. + if (y[0] != 42) { + _exit(1); + } + write(1, "Passed\n", sizeof("Passed\n")); + free(y); + // CHECK: FreeHook + // CHECK: Passed + return 0; +} diff --git a/lib/asan/lit_tests/global-demangle.cc b/lib/asan/lit_tests/TestCases/global-demangle.cc index 5696a38a7705..d050b70f0fca 100644 --- a/lib/asan/lit_tests/global-demangle.cc +++ b/lib/asan/lit_tests/TestCases/global-demangle.cc @@ -1,5 +1,4 @@ -// Don't run through %symbolize to avoid c++filt demangling. -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s namespace XXX { class YYY { diff --git a/lib/asan/lit_tests/TestCases/global-overflow.cc b/lib/asan/lit_tests/TestCases/global-overflow.cc new file mode 100644 index 000000000000..0f080f55f2f1 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/global-overflow.cc @@ -0,0 +1,21 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +#include <string.h> +int main(int argc, char **argv) { + static char XXX[10]; + static char YYY[10]; + static char ZZZ[10]; + memset(XXX, 0, 10); + memset(YYY, 0, 10); + memset(ZZZ, 0, 10); + int res = YYY[argc * 10]; // BOOOM + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*global-overflow.cc:}}[[@LINE-2]] + // CHECK: {{0x.* is located 0 bytes to the right of global variable}} + // CHECK: {{.*YYY.* of size 10}} + res += XXX[argc] + ZZZ[argc]; + return res; +} diff --git a/lib/asan/lit_tests/TestCases/heap-overflow.cc b/lib/asan/lit_tests/TestCases/heap-overflow.cc new file mode 100644 index 000000000000..2c943a36014f --- /dev/null +++ b/lib/asan/lit_tests/TestCases/heap-overflow.cc @@ -0,0 +1,24 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK + +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + char *x = (char*)malloc(10 * sizeof(char)); + memset(x, 0, 10); + int res = x[argc * 10]; // BOOOM + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*heap-overflow.cc:}}[[@LINE-2]] + // CHECK: {{0x.* is located 0 bytes to the right of 10-byte region}} + // CHECK: {{allocated by thread T0 here:}} + + // CHECK-Linux: {{ #0 0x.* in .*malloc}} + // CHECK-Linux: {{ #1 0x.* in main .*heap-overflow.cc:9}} + + // CHECK-Darwin: {{ #0 0x.* in wrap_malloc.*}} + // CHECK-Darwin: {{ #1 0x.* in main .*heap-overflow.cc:9}} + free(x); + return res; +} diff --git a/lib/asan/lit_tests/huge_negative_hea_oob.cc b/lib/asan/lit_tests/TestCases/huge_negative_hea_oob.cc index a09e3bf87d60..58a44c5fb68e 100644 --- a/lib/asan/lit_tests/huge_negative_hea_oob.cc +++ b/lib/asan/lit_tests/TestCases/huge_negative_hea_oob.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_asan -m64 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O %s -o %t && not %t 2>&1 | FileCheck %s // Check that we can find huge buffer overflows to the left. #include <stdlib.h> #include <string.h> diff --git a/lib/asan/lit_tests/init-order-atexit.cc b/lib/asan/lit_tests/TestCases/init-order-atexit.cc index 45f4f17c0cb0..e38cdd273d58 100644 --- a/lib/asan/lit_tests/init-order-atexit.cc +++ b/lib/asan/lit_tests/TestCases/init-order-atexit.cc @@ -4,8 +4,8 @@ // (3) destructor of A reads uninitialized global C from another module. // We do *not* want to report init-order bug in this case. -// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/init-order-atexit-extra.cc -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s %p/Helpers/init-order-atexit-extra.cc -o %t +// RUN: ASAN_OPTIONS=strict_init_order=true not %t 2>&1 | FileCheck %s #include <stdio.h> #include <stdlib.h> diff --git a/lib/asan/lit_tests/init-order-dlopen.cc b/lib/asan/lit_tests/TestCases/init-order-dlopen.cc index 228f44204c99..d30d11999246 100644 --- a/lib/asan/lit_tests/init-order-dlopen.cc +++ b/lib/asan/lit_tests/TestCases/init-order-dlopen.cc @@ -1,14 +1,18 @@ // Regression test for // https://code.google.com/p/address-sanitizer/issues/detail?id=178 -// RUN: %clangxx_asan -m64 -O0 %p/SharedLibs/init-order-dlopen-so.cc \ -// RUN: -fPIC -shared -o %t-so.so +// Assume we're on Darwin and try to pass -U to the linker. If this flag is +// unsupported, don't use it. +// RUN: %clangxx_asan -O0 %p/SharedLibs/init-order-dlopen-so.cc \ +// RUN: -fPIC -shared -o %t-so.so -Wl,-U,_inc_global || \ +// RUN: %clangxx_asan -O0 %p/SharedLibs/init-order-dlopen-so.cc \ +// RUN: -fPIC -shared -o %t-so.so // If the linker doesn't support --export-dynamic (which is ELF-specific), // try to link without that option. // FIXME: find a better solution. -// RUN: %clangxx_asan -m64 -O0 %s -o %t -Wl,--export-dynamic || \ -// RUN: %clangxx_asan -m64 -O0 %s -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true:strict_init_order=true %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t -Wl,--export-dynamic || \ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: ASAN_OPTIONS=strict_init_order=true %t 2>&1 | FileCheck %s #include <dlfcn.h> #include <pthread.h> #include <stdio.h> @@ -24,6 +28,7 @@ int foo() { int global = foo(); __attribute__((visibility("default"))) +extern "C" void inc_global() { global++; } diff --git a/lib/asan/lit_tests/TestCases/init-order-pthread-create.cc b/lib/asan/lit_tests/TestCases/init-order-pthread-create.cc new file mode 100644 index 000000000000..52031216d5bb --- /dev/null +++ b/lib/asan/lit_tests/TestCases/init-order-pthread-create.cc @@ -0,0 +1,32 @@ +// Check that init-order checking is properly disabled if pthread_create is +// called. + +// RUN: %clangxx_asan %s %p/Helpers/init-order-pthread-create-extra.cc -o %t +// RUN: ASAN_OPTIONS=strict_init_order=true %t + +#include <stdio.h> +#include <pthread.h> + +void *run(void *arg) { + return arg; +} + +void *foo(void *input) { + pthread_t t; + pthread_create(&t, 0, run, input); + void *res; + pthread_join(t, &res); + return res; +} + +void *bar(void *input) { + return input; +} + +void *glob = foo((void*)0x1234); +extern void *glob2; + +int main() { + printf("%p %p\n", glob, glob2); + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/initialization-blacklist.cc b/lib/asan/lit_tests/TestCases/initialization-blacklist.cc new file mode 100644 index 000000000000..f40fcc082f9a --- /dev/null +++ b/lib/asan/lit_tests/TestCases/initialization-blacklist.cc @@ -0,0 +1,32 @@ +// Test for blacklist functionality of initialization-order checker. + +// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-blacklist-extra.cc\ +// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ +// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ +// RUN: -fsanitize=init-order -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 +// RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-blacklist-extra.cc\ +// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ +// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ +// RUN: -fsanitize=init-order -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 +// RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-blacklist-extra.cc\ +// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ +// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ +// RUN: -fsanitize=init-order -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 + +// Function is defined in another TU. +int readBadGlobal(); +int x = readBadGlobal(); // init-order bug. + +// Function is defined in another TU. +int accessBadObject(); +int y = accessBadObject(); // init-order bug. + +int readBadSrcGlobal(); +int z = readBadSrcGlobal(); // init-order bug. + +int main(int argc, char **argv) { + return argc + x + y + z - 1; +} diff --git a/lib/asan/lit_tests/initialization-bug.cc b/lib/asan/lit_tests/TestCases/initialization-bug.cc index ee2c725f0b13..fb289b1c7ebe 100644 --- a/lib/asan/lit_tests/initialization-bug.cc +++ b/lib/asan/lit_tests/TestCases/initialization-bug.cc @@ -1,11 +1,7 @@ // Test to make sure basic initialization order errors are caught. -// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \ -// RUN: | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \ -// RUN: | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true not %t 2>&1 | FileCheck %s // Do not test with optimization -- the error may be optimized away. diff --git a/lib/asan/lit_tests/TestCases/initialization-constexpr.cc b/lib/asan/lit_tests/TestCases/initialization-constexpr.cc new file mode 100644 index 000000000000..65c95edd5081 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/initialization-constexpr.cc @@ -0,0 +1,31 @@ +// Constexpr: +// We need to check that a global variable initialized with a constexpr +// constructor can be accessed during dynamic initialization (as a constexpr +// constructor implies that it was initialized during constant initialization, +// not dynamic initialization). + +// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-constexpr-extra.cc\ +// RUN: --std=c++11 -fsanitize=init-order -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 +// RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-constexpr-extra.cc\ +// RUN: --std=c++11 -fsanitize=init-order -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 +// RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-constexpr-extra.cc\ +// RUN: --std=c++11 -fsanitize=init-order -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 +// RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-constexpr-extra.cc\ +// RUN: --std=c++11 -fsanitize=init-order -o %t +// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 + +class Integer { + private: + int value; + + public: + constexpr Integer(int x = 0) : value(x) {} + int getValue() {return value;} +}; +Integer coolestInteger(42); +int getCoolestInteger() { return coolestInteger.getValue(); } + +int main() { return 0; } diff --git a/lib/asan/lit_tests/initialization-nobug.cc b/lib/asan/lit_tests/TestCases/initialization-nobug.cc index 407226e29a1b..ed37d137f8cb 100644 --- a/lib/asan/lit_tests/initialization-nobug.cc +++ b/lib/asan/lit_tests/TestCases/initialization-nobug.cc @@ -1,21 +1,13 @@ // A collection of various initializers which shouldn't trip up initialization // order checking. If successful, this will just return 0. -// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t +// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t // RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t +// RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t // RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t +// RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t // RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O3 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O3 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t +// RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-nobug-extra.cc -fsanitize=init-order -o %t // RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 // Simple access: diff --git a/lib/asan/lit_tests/TestCases/inline.cc b/lib/asan/lit_tests/TestCases/inline.cc new file mode 100644 index 000000000000..792aff59f4ba --- /dev/null +++ b/lib/asan/lit_tests/TestCases/inline.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O3 %s -o %t && %t + +// Test that no_sanitize_address attribute applies even when the function would +// be normally inlined. + +#include <stdlib.h> + +__attribute__((no_sanitize_address)) +int f(int *p) { + return *p; // BOOOM?? Nope! +} + +int main(int argc, char **argv) { + int * volatile x = (int*)malloc(2*sizeof(int) + 2); + int res = f(x + 2); + if (res) + exit(0); + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/interface_test.cc b/lib/asan/lit_tests/TestCases/interface_test.cc new file mode 100644 index 000000000000..297b5526e9d9 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/interface_test.cc @@ -0,0 +1,8 @@ +// Check that user may include ASan interface header. +// RUN: %clang_asan %s -o %t && %t +// RUN: %clang %s -o %t && %t +#include <sanitizer/asan_interface.h> + +int main() { + return 0; +} diff --git a/lib/asan/lit_tests/invalid-free.cc b/lib/asan/lit_tests/TestCases/invalid-free.cc index 0ef064056b63..f940b501279a 100644 --- a/lib/asan/lit_tests/invalid-free.cc +++ b/lib/asan/lit_tests/TestCases/invalid-free.cc @@ -1,4 +1,9 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX + +// Also works if no malloc context is available. +// RUN: ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %t 2>&1 | FileCheck %s #include <stdlib.h> #include <string.h> @@ -11,6 +16,6 @@ int main(int argc, char **argv) { // CHECK: invalid-free.cc:[[@LINE-2]] // CHECK: is located 5 bytes inside of 10-byte region // CHECK: allocated by thread T0 here: - // CHECK: invalid-free.cc:[[@LINE-8]] + // MALLOC-CTX: invalid-free.cc:[[@LINE-8]] return res; } diff --git a/lib/asan/lit_tests/TestCases/ioctl.cc b/lib/asan/lit_tests/TestCases/ioctl.cc new file mode 100644 index 000000000000..08ca688d3872 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/ioctl.cc @@ -0,0 +1,24 @@ +// RUN: %clangxx_asan -O0 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 not %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -O0 -g %s -o %t && %t +// RUN: %clangxx_asan -O3 -g %s -o %t && %t + +#include <assert.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/socket.h> +#include <unistd.h> + +int main(int argc, char **argv) { + int fd = socket(AF_INET, SOCK_DGRAM, 0); + + int nonblock; + int res = ioctl(fd, FIONBIO, &nonblock + 1); + // CHECK: AddressSanitizer: stack-buffer-overflow + // CHECK: READ of size 4 at + // CHECK: {{#.* in main .*ioctl.cc:}}[[@LINE-3]] + assert(res == 0); + close(fd); + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/large_func_test.cc b/lib/asan/lit_tests/TestCases/large_func_test.cc new file mode 100644 index 000000000000..0534bcd31142 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/large_func_test.cc @@ -0,0 +1,51 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK + +#include <stdlib.h> +__attribute__((noinline)) +static void LargeFunction(int *x, int zero) { + x[0]++; + x[1]++; + x[2]++; + x[3]++; + x[4]++; + x[5]++; + x[6]++; + x[7]++; + x[8]++; + x[9]++; + + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} + // CHECK: {{READ of size 4 at 0x.* thread T0}} + x[zero + 103]++; // we should report this exact line + // atos incorrectly extracts the symbol name for the static functions on + // Darwin. + // CHECK-Linux: {{#0 0x.* in LargeFunction.*large_func_test.cc:}}[[@LINE-3]] + // CHECK-Darwin: {{#0 0x.* in .*LargeFunction.*large_func_test.cc}}:[[@LINE-4]] + + x[10]++; + x[11]++; + x[12]++; + x[13]++; + x[14]++; + x[15]++; + x[16]++; + x[17]++; + x[18]++; + x[19]++; +} + +int main(int argc, char **argv) { + int *x = new int[100]; + LargeFunction(x, argc - 1); + // CHECK: {{ #1 0x.* in main .*large_func_test.cc:}}[[@LINE-1]] + // CHECK: {{0x.* is located 12 bytes to the right of 400-byte region}} + // CHECK: {{allocated by thread T0 here:}} + // CHECK-Linux: {{ #0 0x.* in operator new.*}} + // CHECK-Darwin: {{ #0 0x.* in .*_Zna.*}} + // CHECK: {{ #1 0x.* in main .*large_func_test.cc:}}[[@LINE-7]] + delete x; +} diff --git a/lib/asan/lit_tests/log-path_test.cc b/lib/asan/lit_tests/TestCases/log-path_test.cc index 1072670fbff4..1072670fbff4 100644 --- a/lib/asan/lit_tests/log-path_test.cc +++ b/lib/asan/lit_tests/TestCases/log-path_test.cc diff --git a/lib/asan/lit_tests/log_path_fork_test.cc.disabled b/lib/asan/lit_tests/TestCases/log_path_fork_test.cc.disabled index c6c1b49e994d..c6c1b49e994d 100644 --- a/lib/asan/lit_tests/log_path_fork_test.cc.disabled +++ b/lib/asan/lit_tests/TestCases/log_path_fork_test.cc.disabled diff --git a/lib/asan/lit_tests/TestCases/lsan_annotations.cc b/lib/asan/lit_tests/TestCases/lsan_annotations.cc new file mode 100644 index 000000000000..c55ab8692eb5 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/lsan_annotations.cc @@ -0,0 +1,16 @@ +// Check that LSan annotations work fine. +// RUN: %clangxx_asan -O0 %s -o %t && %t +// RUN: %clangxx_asan -O3 %s -o %t && %t + +#include <sanitizer/lsan_interface.h> +#include <stdlib.h> + +int main() { + int *x = new int; + __lsan_ignore_object(x); + { + __lsan::ScopedDisabler disabler; + double *y = new double; + } + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/malloc_context_size.cc b/lib/asan/lit_tests/TestCases/malloc_context_size.cc new file mode 100644 index 000000000000..266ce66f59e2 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/malloc_context_size.cc @@ -0,0 +1,27 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os +// RUN: ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os +// RUN: ASAN_OPTIONS=malloc_context_size=1:fast_unwind_on_malloc=0 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os +// RUN: ASAN_OPTIONS=malloc_context_size=1:fast_unwind_on_malloc=1 not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os + +int main() { + char *x = new char[20]; + delete[] x; + return x[0]; + // We need to keep duplicate lines with different 'CHECK-%os' prefixes, + // otherwise FileCheck barks on missing 'CHECK-%os' before 'CHECK-%os-NEXT'. + + // CHECK-Linux: freed by thread T{{.*}} here: + // CHECK-Linux-NEXT: #0 0x{{.*}} in operator delete[] + // CHECK-Darwin: freed by thread T{{.*}} here: + // CHECK-Darwin-NEXT: #0 0x{{.*}} in wrap__ZdaPv + // CHECK-NOT: #1 0x{{.*}} + + // CHECK-Linux: previously allocated by thread T{{.*}} here: + // CHECK-Linux-NEXT: #0 0x{{.*}} in operator new[] + // CHECK-Darwin: previously allocated by thread T{{.*}} here: + // CHECK-Darwin-NEXT: #0 0x{{.*}} in wrap__Znam + // CHECK-NOT: #1 0x{{.*}} + + // CHECK: SUMMARY: AddressSanitizer: heap-use-after-free +} diff --git a/lib/asan/lit_tests/malloc_fill.cc b/lib/asan/lit_tests/TestCases/malloc_fill.cc index c23516b33299..57f50d1438b7 100644 --- a/lib/asan/lit_tests/malloc_fill.cc +++ b/lib/asan/lit_tests/TestCases/malloc_fill.cc @@ -1,5 +1,5 @@ // Check that we fill malloc-ed memory correctly. -// RUN: %clangxx_asan -m64 %s -o %t +// RUN: %clangxx_asan %s -o %t // RUN: %t | FileCheck %s // RUN: ASAN_OPTIONS=max_malloc_fill_size=10:malloc_fill_byte=8 %t | FileCheck %s --check-prefix=CHECK-10-8 // RUN: ASAN_OPTIONS=max_malloc_fill_size=20:malloc_fill_byte=171 %t | FileCheck %s --check-prefix=CHECK-20-ab diff --git a/lib/asan/lit_tests/malloc_hook.cc b/lib/asan/lit_tests/TestCases/malloc_hook.cc index 6435d105ee26..83be1020ea43 100644 --- a/lib/asan/lit_tests/malloc_hook.cc +++ b/lib/asan/lit_tests/TestCases/malloc_hook.cc @@ -4,19 +4,31 @@ #include <unistd.h> extern "C" { +bool __asan_get_ownership(const void *p); + +void *global_ptr; + // Note: avoid calling functions that allocate memory in malloc/free // to avoid infinite recursion. void __asan_malloc_hook(void *ptr, size_t sz) { - write(1, "MallocHook\n", sizeof("MallocHook\n")); + if (__asan_get_ownership(ptr)) { + write(1, "MallocHook\n", sizeof("MallocHook\n")); + global_ptr = ptr; + } } void __asan_free_hook(void *ptr) { - write(1, "FreeHook\n", sizeof("FreeHook\n")); + if (__asan_get_ownership(ptr) && ptr == global_ptr) + write(1, "FreeHook\n", sizeof("FreeHook\n")); } } // extern "C" int main() { volatile int *x = new int; // CHECK: MallocHook + // Check that malloc hook was called with correct argument. + if (global_ptr != (void*)x) { + _exit(1); + } *x = 0; delete x; // CHECK: FreeHook diff --git a/lib/asan/lit_tests/TestCases/memcmp_strict_test.cc b/lib/asan/lit_tests/TestCases/memcmp_strict_test.cc new file mode 100644 index 000000000000..e06a8c7e9e2f --- /dev/null +++ b/lib/asan/lit_tests/TestCases/memcmp_strict_test.cc @@ -0,0 +1,15 @@ +// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=strict_memcmp=0 %t +// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=strict_memcmp=1 not %t 2>&1 | FileCheck %s +// Default to strict_memcmp=1. +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <string.h> +int main() { + char kFoo[] = "foo"; + char kFubar[] = "fubar"; + int res = memcmp(kFoo, kFubar, strlen(kFubar)); + printf("res: %d\n", res); + // CHECK: AddressSanitizer: stack-buffer-overflow + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/memcmp_test.cc b/lib/asan/lit_tests/TestCases/memcmp_test.cc new file mode 100644 index 000000000000..758311ddc476 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/memcmp_test.cc @@ -0,0 +1,17 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// REQUIRES: compiler-rt-optimized + +#include <string.h> +int main(int argc, char **argv) { + char a1[] = {argc, 2, 3, 4}; + char a2[] = {1, 2*argc, 3, 4}; + int res = memcmp(a1, a2, 4 + argc); // BOOM + // CHECK: AddressSanitizer: stack-buffer-overflow + // CHECK: {{#0.*memcmp}} + // CHECK: {{#1.*main}} + return res; +} diff --git a/lib/asan/lit_tests/TestCases/null_deref.cc b/lib/asan/lit_tests/TestCases/null_deref.cc new file mode 100644 index 000000000000..476418324cc5 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/null_deref.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK + +__attribute__((noinline)) +static void NullDeref(int *ptr) { + // CHECK: ERROR: AddressSanitizer: SEGV on unknown address + // CHECK: {{0x0*00028 .*pc 0x.*}} + ptr[10]++; // BOOM + // atos on Mac cannot extract the symbol name correctly. + // CHECK-Linux: {{ #0 0x.* in NullDeref.*null_deref.cc:}}[[@LINE-2]] + // CHECK-Darwin: {{ #0 0x.* in .*NullDeref.*null_deref.cc:}}[[@LINE-3]] +} +int main() { + NullDeref((int*)0); + // CHECK: {{ #1 0x.* in main.*null_deref.cc:}}[[@LINE-1]] + // CHECK: {{AddressSanitizer can not provide additional info.}} +} diff --git a/lib/asan/lit_tests/on_error_callback.cc b/lib/asan/lit_tests/TestCases/on_error_callback.cc index bb94d9fb579b..d0cec2eb2703 100644 --- a/lib/asan/lit_tests/on_error_callback.cc +++ b/lib/asan/lit_tests/TestCases/on_error_callback.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -O2 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s #include <stdio.h> #include <stdlib.h> diff --git a/lib/asan/lit_tests/TestCases/partial_right.cc b/lib/asan/lit_tests/TestCases/partial_right.cc new file mode 100644 index 000000000000..a000a913d6be --- /dev/null +++ b/lib/asan/lit_tests/TestCases/partial_right.cc @@ -0,0 +1,13 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +#include <stdlib.h> +int main(int argc, char **argv) { + volatile int *x = (int*)malloc(2*sizeof(int) + 2); + int res = x[2]; // BOOOM + // CHECK: {{READ of size 4 at 0x.* thread T0}} + // CHECK: [[ADDR:0x[01-9a-fa-f]+]] is located 0 bytes to the right of {{.*}}-byte region [{{.*}},{{.*}}[[ADDR]]) + return res; +} diff --git a/lib/asan/lit_tests/TestCases/poison_partial.cc b/lib/asan/lit_tests/TestCases/poison_partial.cc new file mode 100644 index 000000000000..f7c48bf597b6 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/poison_partial.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %t 2>&1 | FileCheck %s +// RUN: not %t heap 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=poison_partial=0 %t +// RUN: ASAN_OPTIONS=poison_partial=0 %t heap +#include <string.h> +char g[21]; +char *x; + +int main(int argc, char **argv) { + if (argc >= 2) + x = new char[21]; + else + x = &g[0]; + memset(x, 0, 21); + int *y = (int*)x; + return y[5]; +} +// CHECK: 0 bytes to the right diff --git a/lib/asan/lit_tests/TestCases/print_summary.cc b/lib/asan/lit_tests/TestCases/print_summary.cc new file mode 100644 index 000000000000..949c9b54f8a3 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/print_summary.cc @@ -0,0 +1,14 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %t 2>&1 | FileCheck %s --check-prefix=YES +// RUN: ASAN_OPTIONS=print_summary=false not %t 2>&1 | FileCheck %s --check-prefix=NO + +int main() { + char *x = new char[20]; + delete[] x; + return x[0]; + // YES: ERROR: AddressSanitizer: heap-use-after-free + // YES: SUMMARY: AddressSanitizer: heap-use-after-free + // NO: ERROR: AddressSanitizer: heap-use-after-free + // NO-NOT: SUMMARY: AddressSanitizer: heap-use-after-free +} + diff --git a/lib/asan/lit_tests/TestCases/readv.cc b/lib/asan/lit_tests/TestCases/readv.cc new file mode 100644 index 000000000000..ba17505f37ac --- /dev/null +++ b/lib/asan/lit_tests/TestCases/readv.cc @@ -0,0 +1,32 @@ +// RUN: %clangxx_asan -O0 %s -o %t && %t +// RUN: %clangxx_asan -O0 %s -DPOSITIVE -o %t && not %t 2>&1 | FileCheck %s + +// Test the readv() interceptor. + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/uio.h> +#include <time.h> + +int main() { + char buf[2011]; + struct iovec iov[2]; +#ifdef POSITIVE + char * volatile buf_ = buf; + iov[0].iov_base = buf_ - 1; +#else + iov[0].iov_base = buf + 1; +#endif + iov[0].iov_len = 5; + iov[1].iov_base = buf + 10; + iov[1].iov_len = 2000; + int fd = open("/etc/hosts", O_RDONLY); + assert(fd > 0); + readv(fd, iov, 2); + // CHECK: WRITE of size 5 at + close(fd); + return 0; +} diff --git a/lib/asan/lit_tests/sanity_check_pure_c.c b/lib/asan/lit_tests/TestCases/sanity_check_pure_c.c index 3d830653e33e..df150675bd97 100644 --- a/lib/asan/lit_tests/sanity_check_pure_c.c +++ b/lib/asan/lit_tests/TestCases/sanity_check_pure_c.c @@ -1,10 +1,10 @@ // Sanity checking a test in pure C. -// RUN: %clang -g -fsanitize=address -O2 %s -o %t -// RUN: %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clang_asan -O2 %s -o %t +// RUN: not %t 2>&1 | FileCheck %s // Sanity checking a test in pure C with -pie. -// RUN: %clang -g -fsanitize=address -O2 %s -pie -o %t -// RUN: %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clang_asan -O2 %s -pie -o %t +// RUN: not %t 2>&1 | FileCheck %s #include <stdlib.h> int main() { diff --git a/lib/asan/lit_tests/TestCases/shared-lib-test.cc b/lib/asan/lit_tests/TestCases/shared-lib-test.cc new file mode 100644 index 000000000000..126903a55866 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/shared-lib-test.cc @@ -0,0 +1,42 @@ +// RUN: %clangxx_asan -O0 %p/SharedLibs/shared-lib-test-so.cc \ +// RUN: -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %p/SharedLibs/shared-lib-test-so.cc \ +// RUN: -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %p/SharedLibs/shared-lib-test-so.cc \ +// RUN: -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %p/SharedLibs/shared-lib-test-so.cc \ +// RUN: -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +#include <dlfcn.h> +#include <stdio.h> +#include <string.h> + +#include <string> + +using std::string; + +typedef void (fun_t)(int x); + +int main(int argc, char *argv[]) { + string path = string(argv[0]) + "-so.so"; + printf("opening %s ... \n", path.c_str()); + void *lib = dlopen(path.c_str(), RTLD_NOW); + if (!lib) { + printf("error in dlopen(): %s\n", dlerror()); + return 1; + } + fun_t *inc = (fun_t*)dlsym(lib, "inc"); + if (!inc) return 1; + printf("ok\n"); + inc(1); + inc(-1); // BOOM + // CHECK: {{.*ERROR: AddressSanitizer: global-buffer-overflow}} + // CHECK: {{READ of size 4 at 0x.* thread T0}} + // CHECK: {{ #0 0x.*}} + // CHECK: {{ #1 0x.* in main .*shared-lib-test.cc:}}[[@LINE-4]] + return 0; +} diff --git a/lib/asan/lit_tests/sleep_before_dying.c b/lib/asan/lit_tests/TestCases/sleep_before_dying.c index df9eba276039..8dee9f2778ce 100644 --- a/lib/asan/lit_tests/sleep_before_dying.c +++ b/lib/asan/lit_tests/TestCases/sleep_before_dying.c @@ -1,5 +1,5 @@ -// RUN: %clang -g -fsanitize=address -O2 %s -o %t -// RUN: ASAN_OPTIONS="sleep_before_dying=1" %t 2>&1 | FileCheck %s +// RUN: %clang_asan -O2 %s -o %t +// RUN: ASAN_OPTIONS="sleep_before_dying=1" not %t 2>&1 | FileCheck %s #include <stdlib.h> int main() { diff --git a/lib/asan/lit_tests/TestCases/stack-buffer-overflow-with-position.cc b/lib/asan/lit_tests/TestCases/stack-buffer-overflow-with-position.cc new file mode 100644 index 000000000000..91820db0142a --- /dev/null +++ b/lib/asan/lit_tests/TestCases/stack-buffer-overflow-with-position.cc @@ -0,0 +1,45 @@ +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: not %t -2 2>&1 | FileCheck --check-prefix=CHECK-m2 %s +// RUN: not %t -1 2>&1 | FileCheck --check-prefix=CHECK-m1 %s +// RUN: %t 0 +// RUN: %t 8 +// RUN: not %t 9 2>&1 | FileCheck --check-prefix=CHECK-9 %s +// RUN: not %t 10 2>&1 | FileCheck --check-prefix=CHECK-10 %s +// RUN: not %t 62 2>&1 | FileCheck --check-prefix=CHECK-62 %s +// RUN: not %t 63 2>&1 | FileCheck --check-prefix=CHECK-63 %s +// RUN: not %t 63 2>&1 | FileCheck --check-prefix=CHECK-63 %s +// RUN: not %t 73 2>&1 | FileCheck --check-prefix=CHECK-73 %s +// RUN: not %t 74 2>&1 | FileCheck --check-prefix=CHECK-74 %s +// RUN: not %t 126 2>&1 | FileCheck --check-prefix=CHECK-126 %s +// RUN: not %t 127 2>&1 | FileCheck --check-prefix=CHECK-127 %s +// RUN: not %t 137 2>&1 | FileCheck --check-prefix=CHECK-137 %s +// RUN: not %t 138 2>&1 | FileCheck --check-prefix=CHECK-138 %s +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +int main(int argc, char **argv) { + assert(argc >= 2); + int idx = atoi(argv[1]); + char AAA[10], BBB[10], CCC[10]; + memset(AAA, 0, sizeof(AAA)); + memset(BBB, 0, sizeof(BBB)); + memset(CCC, 0, sizeof(CCC)); + int res = 0; + char *p = AAA + idx; + printf("AAA: %p\ny: %p\nz: %p\np: %p\n", AAA, BBB, CCC, p); + // make sure BBB and CCC are not removed; + return *(short*)(p) + BBB[argc % 2] + CCC[argc % 2]; +} +// CHECK-m2: 'AAA' <== Memory access at offset 30 underflows this variable +// CHECK-m1: 'AAA' <== Memory access at offset 31 partially underflows this variable +// CHECK-9: 'AAA' <== Memory access at offset 41 partially overflows this variable +// CHECK-10: 'AAA' <== Memory access at offset 42 overflows this variable +// CHECK-62: 'BBB' <== Memory access at offset 94 underflows this variable +// CHECK-63: 'BBB' <== Memory access at offset 95 partially underflows this variable +// CHECK-73: 'BBB' <== Memory access at offset 105 partially overflows this variable +// CHECK-74: 'BBB' <== Memory access at offset 106 overflows this variable +// CHECK-126: 'CCC' <== Memory access at offset 158 underflows this variable +// CHECK-127: 'CCC' <== Memory access at offset 159 partially underflows this variable +// CHECK-137: 'CCC' <== Memory access at offset 169 partially overflows this variable +// CHECK-138: 'CCC' <== Memory access at offset 170 overflows this variable diff --git a/lib/asan/lit_tests/stack-frame-demangle.cc b/lib/asan/lit_tests/TestCases/stack-frame-demangle.cc index bb8de16b2b8a..2b83ecc2923b 100644 --- a/lib/asan/lit_tests/stack-frame-demangle.cc +++ b/lib/asan/lit_tests/TestCases/stack-frame-demangle.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s #include <string.h> diff --git a/lib/asan/lit_tests/stack-oob-frames.cc b/lib/asan/lit_tests/TestCases/stack-oob-frames.cc index 0395522252e8..909e700b3d00 100644 --- a/lib/asan/lit_tests/stack-oob-frames.cc +++ b/lib/asan/lit_tests/TestCases/stack-oob-frames.cc @@ -1,8 +1,8 @@ -// RUN: %clangxx_asan -m64 -O1 %s -o %t -// RUN: %t 0 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK0 -// RUN: %t 1 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK1 -// RUN: %t 2 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK2 -// RUN: %t 3 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK3 +// RUN: %clangxx_asan -O1 %s -o %t +// RUN: not %t 0 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: not %t 1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: not %t 2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: not %t 3 2>&1 | FileCheck %s --check-prefix=CHECK3 #define NOINLINE __attribute__((noinline)) inline void break_optimization(void *arg) { diff --git a/lib/asan/lit_tests/TestCases/stack-overflow.cc b/lib/asan/lit_tests/TestCases/stack-overflow.cc new file mode 100644 index 000000000000..adf1c0784f70 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/stack-overflow.cc @@ -0,0 +1,16 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +#include <string.h> +int main(int argc, char **argv) { + char x[10]; + memset(x, 0, 10); + int res = x[argc * 10]; // BOOOM + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*stack-overflow.cc:}}[[@LINE-2]] + // CHECK: {{Address 0x.* is located in stack of thread T0 at offset}} + // CHECK-NEXT: in{{.*}}main{{.*}}stack-overflow.cc + return res; +} diff --git a/lib/asan/lit_tests/TestCases/stack-use-after-return.cc b/lib/asan/lit_tests/TestCases/stack-use-after-return.cc new file mode 100644 index 000000000000..5ed42a8c0c97 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/stack-use-after-return.cc @@ -0,0 +1,77 @@ +// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: %clangxx_asan -O0 %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=detect_stack_use_after_return=0 %t +// Regression test for a CHECK failure with small stack size and large frame. +// RUN: %clangxx_asan -O3 %s -o %t -DkSize=10000 && \ +// RUN: (ulimit -s 65; not %t) 2>&1 | FileCheck %s +// +// Test that we can find UAR in a thread other than main: +// RUN: %clangxx_asan -DUseThread -O2 %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck --check-prefix=THREAD %s +// +// Test the uar_stack_size_log flag. +// +// RUN: ASAN_OPTIONS=$ASAN_OPTIONS:uar_stack_size_log=20:verbosity=1 not %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s +// RUN: ASAN_OPTIONS=$ASAN_OPTIONS:uar_stack_size_log=24:verbosity=1 not %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s + +#include <stdio.h> +#include <pthread.h> + +#ifndef kSize +# define kSize 1 +#endif + +#ifndef UseThread +# define UseThread 0 +#endif + +__attribute__((noinline)) +char *Ident(char *x) { + fprintf(stderr, "1: %p\n", x); + return x; +} + +__attribute__((noinline)) +char *Func1() { + char local[kSize]; + return Ident(local); +} + +__attribute__((noinline)) +void Func2(char *x) { + fprintf(stderr, "2: %p\n", x); + *x = 1; + // CHECK: WRITE of size 1 {{.*}} thread T0 + // CHECK: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-2]] + // CHECK: is located in stack of thread T0 at offset + // CHECK: 'local' <== Memory access at offset 32 is inside this variable + // THREAD: WRITE of size 1 {{.*}} thread T{{[1-9]}} + // THREAD: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-6]] + // THREAD: is located in stack of thread T{{[1-9]}} at offset + // THREAD: 'local' <== Memory access at offset 32 is inside this variable + // CHECK-20: T0: FakeStack created:{{.*}} stack_size_log: 20 + // CHECK-24: T0: FakeStack created:{{.*}} stack_size_log: 24 +} + +void *Thread(void *unused) { + Func2(Func1()); + return NULL; +} + +int main(int argc, char **argv) { +#if UseThread + pthread_t t; + pthread_create(&t, 0, Thread, 0); + pthread_join(t, 0); +#else + Func2(Func1()); +#endif + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/strdup_oob_test.cc b/lib/asan/lit_tests/TestCases/strdup_oob_test.cc new file mode 100644 index 000000000000..e92afd3caaf9 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/strdup_oob_test.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +#include <string.h> + +char kString[] = "foo"; + +int main(int argc, char **argv) { + char *copy = strdup(kString); + int x = copy[4 + argc]; // BOOM + // CHECK: AddressSanitizer: heap-buffer-overflow + // CHECK: #0 {{.*}}main {{.*}}strdup_oob_test.cc:[[@LINE-2]] + // CHECK: allocated by thread T{{.*}} here: + // CHECK: #0 {{.*}}strdup + // CHECK: strdup_oob_test.cc:[[@LINE-6]] + return x; +} diff --git a/lib/asan/lit_tests/TestCases/strerror_r_test.cc b/lib/asan/lit_tests/TestCases/strerror_r_test.cc new file mode 100644 index 000000000000..0df009b83f9c --- /dev/null +++ b/lib/asan/lit_tests/TestCases/strerror_r_test.cc @@ -0,0 +1,13 @@ +// RUN: %clangxx_asan -O0 %s -o %t && %t + +// Regression test for PR17138. + +#include <assert.h> +#include <string.h> + +int main() { + char buf[1024]; + char *res = (char *)strerror_r(300, buf, sizeof(buf)); + assert(res != 0); + return 0; +} diff --git a/lib/asan/lit_tests/strip_path_prefix.c b/lib/asan/lit_tests/TestCases/strip_path_prefix.c index ef7bf98ab3c2..c4d6ba49d5e3 100644 --- a/lib/asan/lit_tests/strip_path_prefix.c +++ b/lib/asan/lit_tests/TestCases/strip_path_prefix.c @@ -1,5 +1,5 @@ -// RUN: %clang -g -fsanitize=address -O2 %s -o %t -// RUN: ASAN_OPTIONS="strip_path_prefix='/'" %t 2>&1 | FileCheck %s +// RUN: %clang_asan -O2 %s -o %t +// RUN: ASAN_OPTIONS="strip_path_prefix='/'" not %t 2>&1 | FileCheck %s #include <stdlib.h> int main() { diff --git a/lib/asan/lit_tests/TestCases/strncpy-overflow.cc b/lib/asan/lit_tests/TestCases/strncpy-overflow.cc new file mode 100644 index 000000000000..f91e191fde23 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/strncpy-overflow.cc @@ -0,0 +1,28 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK + +// REQUIRES: compiler-rt-optimized + +#include <string.h> +#include <stdlib.h> +int main(int argc, char **argv) { + char *hello = (char*)malloc(6); + strcpy(hello, "hello"); + char *short_buffer = (char*)malloc(9); + strncpy(short_buffer, hello, 10); // BOOM + // CHECK: {{WRITE of size 10 at 0x.* thread T0}} + // CHECK-Linux: {{ #0 0x.* in .*strncpy}} + // CHECK-Darwin: {{ #0 0x.* in wrap_strncpy}} + // CHECK: {{ #1 0x.* in main .*strncpy-overflow.cc:}}[[@LINE-4]] + // CHECK: {{0x.* is located 0 bytes to the right of 9-byte region}} + // CHECK: {{allocated by thread T0 here:}} + + // CHECK-Linux: {{ #0 0x.* in .*malloc}} + // CHECK-Linux: {{ #1 0x.* in main .*strncpy-overflow.cc:}}[[@LINE-10]] + + // CHECK-Darwin: {{ #0 0x.* in wrap_malloc.*}} + // CHECK-Darwin: {{ #1 0x.* in main .*strncpy-overflow.cc:}}[[@LINE-13]] + return short_buffer[8]; +} diff --git a/lib/asan/lit_tests/symbolize_callback.cc b/lib/asan/lit_tests/TestCases/symbolize_callback.cc index 0691d501e24d..058b3150fbba 100644 --- a/lib/asan/lit_tests/symbolize_callback.cc +++ b/lib/asan/lit_tests/TestCases/symbolize_callback.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -O2 %s -o %t && %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s #include <stdio.h> #include <stdlib.h> diff --git a/lib/asan/lit_tests/throw_call_test.cc b/lib/asan/lit_tests/TestCases/throw_call_test.cc index 974bc51d97c5..974bc51d97c5 100644 --- a/lib/asan/lit_tests/throw_call_test.cc +++ b/lib/asan/lit_tests/TestCases/throw_call_test.cc diff --git a/lib/asan/lit_tests/throw_invoke_test.cc b/lib/asan/lit_tests/TestCases/throw_invoke_test.cc index 077a940e8d19..077a940e8d19 100644 --- a/lib/asan/lit_tests/throw_invoke_test.cc +++ b/lib/asan/lit_tests/TestCases/throw_invoke_test.cc diff --git a/lib/asan/lit_tests/time_interceptor.cc b/lib/asan/lit_tests/TestCases/time_interceptor.cc index f5f2ad62b815..3be00d60c01d 100644 --- a/lib/asan/lit_tests/time_interceptor.cc +++ b/lib/asan/lit_tests/TestCases/time_interceptor.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s // Test the time() interceptor. diff --git a/lib/asan/lit_tests/TestCases/uar_and_exceptions.cc b/lib/asan/lit_tests/TestCases/uar_and_exceptions.cc new file mode 100644 index 000000000000..c967531c2c02 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/uar_and_exceptions.cc @@ -0,0 +1,40 @@ +// Test that use-after-return works with exceptions. +// export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: %clangxx_asan -O0 %s -o %t && %t + +#include <stdio.h> + +volatile char *g; + +#ifndef FRAME_SIZE +# define FRAME_SIZE 100 +#endif + +#ifndef NUM_ITER +# define NUM_ITER 4000 +#endif + +#ifndef DO_THROW +# define DO_THROW 1 +#endif + +void Func(int depth) { + char frame[FRAME_SIZE]; + g = &frame[0]; + if (depth) + Func(depth - 1); + else if (DO_THROW) + throw 1; +} + +int main(int argc, char **argv) { + for (int i = 0; i < NUM_ITER; i++) { + try { + Func(argc * 100); + } catch(...) { + } + if ((i % (NUM_ITER / 10)) == 0) + fprintf(stderr, "done [%d]\n", i); + } + return 0; +} diff --git a/lib/asan/lit_tests/unaligned_loads_and_stores.cc b/lib/asan/lit_tests/TestCases/unaligned_loads_and_stores.cc index bcae089b427b..d50566c44e9a 100644 --- a/lib/asan/lit_tests/unaligned_loads_and_stores.cc +++ b/lib/asan/lit_tests/TestCases/unaligned_loads_and_stores.cc @@ -1,15 +1,15 @@ -// RUN: %clangxx_asan -O0 -I %p/../../../include %s -o %t -// RUN: %t A 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-A %s -// RUN: %t B 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-B %s -// RUN: %t C 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-C %s -// RUN: %t D 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-D %s -// RUN: %t E 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-E %s +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %t A 2>&1 | FileCheck --check-prefix=CHECK-A %s +// RUN: not %t B 2>&1 | FileCheck --check-prefix=CHECK-B %s +// RUN: not %t C 2>&1 | FileCheck --check-prefix=CHECK-C %s +// RUN: not %t D 2>&1 | FileCheck --check-prefix=CHECK-D %s +// RUN: not %t E 2>&1 | FileCheck --check-prefix=CHECK-E %s -// RUN: %t K 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-K %s -// RUN: %t L 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-L %s -// RUN: %t M 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-M %s -// RUN: %t N 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-N %s -// RUN: %t O 2>&1 | %symbolize | FileCheck --check-prefix=CHECK-O %s +// RUN: not %t K 2>&1 | FileCheck --check-prefix=CHECK-K %s +// RUN: not %t L 2>&1 | FileCheck --check-prefix=CHECK-L %s +// RUN: not %t M 2>&1 | FileCheck --check-prefix=CHECK-M %s +// RUN: not %t N 2>&1 | FileCheck --check-prefix=CHECK-N %s +// RUN: not %t O 2>&1 | FileCheck --check-prefix=CHECK-O %s #include <sanitizer/asan_interface.h> diff --git a/lib/asan/lit_tests/TestCases/use-after-free-right.cc b/lib/asan/lit_tests/TestCases/use-after-free-right.cc new file mode 100644 index 000000000000..88d91f53d24e --- /dev/null +++ b/lib/asan/lit_tests/TestCases/use-after-free-right.cc @@ -0,0 +1,34 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK + +// Test use-after-free report in the case when access is at the right border of +// the allocation. + +#include <stdlib.h> +int main() { + volatile char *x = (char*)malloc(sizeof(char)); + free((void*)x); + *x = 42; + // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} + // CHECK: {{WRITE of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*use-after-free-right.cc:13}} + // CHECK: {{0x.* is located 0 bytes inside of 1-byte region .0x.*,0x.*}} + // CHECK: {{freed by thread T0 here:}} + + // CHECK-Linux: {{ #0 0x.* in .*free}} + // CHECK-Linux: {{ #1 0x.* in main .*use-after-free-right.cc:12}} + + // CHECK-Darwin: {{ #0 0x.* in wrap_free}} + // CHECK-Darwin: {{ #1 0x.* in main .*use-after-free-right.cc:12}} + + // CHECK: {{previously allocated by thread T0 here:}} + + // CHECK-Linux: {{ #0 0x.* in .*malloc}} + // CHECK-Linux: {{ #1 0x.* in main .*use-after-free-right.cc:11}} + + // CHECK-Darwin: {{ #0 0x.* in wrap_malloc.*}} + // CHECK-Darwin: {{ #1 0x.* in main .*use-after-free-right.cc:11}} +} diff --git a/lib/asan/lit_tests/TestCases/use-after-free.cc b/lib/asan/lit_tests/TestCases/use-after-free.cc new file mode 100644 index 000000000000..84ba479c1393 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/use-after-free.cc @@ -0,0 +1,31 @@ +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O1 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O2 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK +// RUN: %clangxx_asan -O3 %s -o %t && not %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK + +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return x[5]; + // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main .*use-after-free.cc:10}} + // CHECK: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}} + // CHECK: {{freed by thread T0 here:}} + + // CHECK-Linux: {{ #0 0x.* in .*free}} + // CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:9}} + + // CHECK-Darwin: {{ #0 0x.* in wrap_free}} + // CHECK-Darwin: {{ #1 0x.* in main .*use-after-free.cc:9}} + + // CHECK: {{previously allocated by thread T0 here:}} + + // CHECK-Linux: {{ #0 0x.* in .*malloc}} + // CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:8}} + + // CHECK-Darwin: {{ #0 0x.* in wrap_malloc.*}} + // CHECK-Darwin: {{ #1 0x.* in main .*use-after-free.cc:8}} +} diff --git a/lib/asan/lit_tests/use-after-poison.cc b/lib/asan/lit_tests/TestCases/use-after-poison.cc index d87342900245..e3bc6ecee7f2 100644 --- a/lib/asan/lit_tests/use-after-poison.cc +++ b/lib/asan/lit_tests/TestCases/use-after-poison.cc @@ -1,5 +1,5 @@ // Check that __asan_poison_memory_region works. -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && not %t 2>&1 | FileCheck %s // // Check that we can disable it // RUN: ASAN_OPTIONS=allow_user_poisoning=0 %t diff --git a/lib/asan/lit_tests/TestCases/use-after-scope-dtor-order.cc b/lib/asan/lit_tests/TestCases/use-after-scope-dtor-order.cc new file mode 100644 index 000000000000..32fa6ad8a464 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/use-after-scope-dtor-order.cc @@ -0,0 +1,25 @@ +// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s +#include <stdio.h> + +struct IntHolder { + explicit IntHolder(int *val = 0) : val_(val) { } + ~IntHolder() { + printf("Value: %d\n", *val_); // BOOM + // CHECK: ERROR: AddressSanitizer: stack-use-after-scope + // CHECK: #0 0x{{.*}} in IntHolder::~IntHolder{{.*}}use-after-scope-dtor-order.cc:[[@LINE-2]] + } + void set(int *val) { val_ = val; } + int *get() { return val_; } + + int *val_; +}; + +int main(int argc, char *argv[]) { + // It is incorrect to use "x" int IntHolder destructor, because "x" is + // "destroyed" earlier as it's declared later. + IntHolder holder; + int x = argc; + holder.set(&x); + return 0; +} diff --git a/lib/asan/lit_tests/use-after-scope-inlined.cc b/lib/asan/lit_tests/TestCases/use-after-scope-inlined.cc index 5c121ea187eb..0bad048e3b8f 100644 --- a/lib/asan/lit_tests/use-after-scope-inlined.cc +++ b/lib/asan/lit_tests/TestCases/use-after-scope-inlined.cc @@ -2,10 +2,7 @@ // happens. "always_inline" is not enough, as Clang doesn't emit // llvm.lifetime intrinsics at -O0. // -// RUN: %clangxx_asan -m64 -O2 -fsanitize=use-after-scope %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 -fsanitize=use-after-scope %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s +// RUN: %clangxx_asan -O2 -fsanitize=use-after-scope %s -o %t && not %t 2>&1 | FileCheck %s int *arr; @@ -21,7 +18,7 @@ int main(int argc, char *argv[]) { return arr[argc - 1]; // BOOM // CHECK: ERROR: AddressSanitizer: stack-use-after-scope // CHECK: READ of size 4 at 0x{{.*}} thread T0 - // CHECK: #0 0x{{.*}} in {{_?}}main + // CHECK: #0 0x{{.*}} in main // CHECK: {{.*}}use-after-scope-inlined.cc:[[@LINE-4]] // CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset // CHECK: [[OFFSET:[^ ]*]] in frame diff --git a/lib/asan/lit_tests/TestCases/use-after-scope-nobug.cc b/lib/asan/lit_tests/TestCases/use-after-scope-nobug.cc new file mode 100644 index 000000000000..c23acf76eaee --- /dev/null +++ b/lib/asan/lit_tests/TestCases/use-after-scope-nobug.cc @@ -0,0 +1,14 @@ +// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && %t + +#include <stdio.h> + +int main() { + int *p = 0; + // Variable goes in and out of scope. + for (int i = 0; i < 3; i++) { + int x = 0; + p = &x; + } + printf("PASSED\n"); + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/use-after-scope-temp.cc b/lib/asan/lit_tests/TestCases/use-after-scope-temp.cc new file mode 100644 index 000000000000..13d714f9def7 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/use-after-scope-temp.cc @@ -0,0 +1,29 @@ +// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \ +// RUN: %t 2>&1 | FileCheck %s +// +// Lifetime for temporaries is not emitted yet. +// XFAIL: * + +#include <stdio.h> + +struct IntHolder { + explicit IntHolder(int val) : val(val) { + printf("IntHolder: %d\n", val); + } + int val; +}; + +const IntHolder *saved; + +void save(const IntHolder &holder) { + saved = &holder; +} + +int main(int argc, char *argv[]) { + save(IntHolder(10)); + int x = saved->val; // BOOM + // CHECK: ERROR: AddressSanitizer: stack-use-after-scope + // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope-temp.cc:[[@LINE-2]] + printf("saved value: %d\n", x); + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/use-after-scope.cc b/lib/asan/lit_tests/TestCases/use-after-scope.cc new file mode 100644 index 000000000000..c46c9594c314 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/use-after-scope.cc @@ -0,0 +1,16 @@ +// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \ +// RUN: not %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS="detect_stack_use_after_return=1" not %t 2>&1 | FileCheck %s + +int main() { + int *p = 0; + { + int x = 0; + p = &x; + } + return *p; // BOOM + // CHECK: ERROR: AddressSanitizer: stack-use-after-scope + // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope.cc:[[@LINE-2]] + // CHECK: Address 0x{{.*}} is located in stack of thread T{{.*}} at offset [[OFFSET:[^ ]+]] in frame + // {{\[}}[[OFFSET]], {{[0-9]+}}) 'x' +} diff --git a/lib/asan/lit_tests/TestCases/wait.cc b/lib/asan/lit_tests/TestCases/wait.cc new file mode 100644 index 000000000000..b5580dc88675 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/wait.cc @@ -0,0 +1,63 @@ +// RUN: %clangxx_asan -DWAIT -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAIT -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -DWAITPID -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAITPID -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -DWAITID -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAITID -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -DWAIT3 -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAIT3 -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -DWAIT4 -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAIT4 -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -DWAIT3_RUSAGE -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAIT3_RUSAGE -O3 %s -o %t && not %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -DWAIT4_RUSAGE -O0 %s -o %t && not %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAIT4_RUSAGE -O3 %s -o %t && not %t 2>&1 | FileCheck %s + + +#include <assert.h> +#include <sys/wait.h> +#include <unistd.h> + +int main(int argc, char **argv) { + pid_t pid = fork(); + if (pid) { // parent + int x[3]; + int *status = x + argc * 3; + int res; +#if defined(WAIT) + res = wait(status); +#elif defined(WAITPID) + res = waitpid(pid, status, WNOHANG); +#elif defined(WAITID) + siginfo_t *si = (siginfo_t*)(x + argc * 3); + res = waitid(P_ALL, 0, si, WEXITED | WNOHANG); +#elif defined(WAIT3) + res = wait3(status, WNOHANG, NULL); +#elif defined(WAIT4) + res = wait4(pid, status, WNOHANG, NULL); +#elif defined(WAIT3_RUSAGE) || defined(WAIT4_RUSAGE) + struct rusage *ru = (struct rusage*)(x + argc * 3); + int good_status; +# if defined(WAIT3_RUSAGE) + res = wait3(&good_status, WNOHANG, ru); +# elif defined(WAIT4_RUSAGE) + res = wait4(pid, &good_status, WNOHANG, ru); +# endif +#endif + // CHECK: stack-buffer-overflow + // CHECK: {{WRITE of size .* at 0x.* thread T0}} + // CHECK: {{in .*wait}} + // CHECK: {{in main .*wait.cc:}} + // CHECK: is located in stack of thread T0 at offset + // CHECK: {{in main}} + return res != -1; + } + // child + return 0; +} diff --git a/lib/asan/lit_tests/Unit/lit.cfg b/lib/asan/lit_tests/Unit/lit.cfg deleted file mode 100644 index e24361b014e9..000000000000 --- a/lib/asan/lit_tests/Unit/lit.cfg +++ /dev/null @@ -1,26 +0,0 @@ -# -*- Python -*- - -import os - -def get_required_attr(config, attr_name): - attr_value = getattr(config, attr_name, None) - if not attr_value: - lit.fatal("No attribute %r in test configuration! You may need to run " - "tests from your build directory or add this attribute " - "to lit.site.cfg " % attr_name) - return attr_value - -# Setup attributes common for all compiler-rt projects. -compiler_rt_src_root = get_required_attr(config, 'compiler_rt_src_root') -compiler_rt_lit_unit_cfg = os.path.join(compiler_rt_src_root, "lib", - "lit.common.unit.cfg") -lit.load_config(config, compiler_rt_lit_unit_cfg) - -# Setup config name. -config.name = 'AddressSanitizer-Unit' - -# Setup test source and exec root. For unit tests, we define -# it as build directory with ASan unit tests. -asan_binary_dir = get_required_attr(config, "asan_binary_dir") -config.test_exec_root = os.path.join(asan_binary_dir, "tests") -config.test_source_root = config.test_exec_root diff --git a/lib/asan/lit_tests/Unit/lit.site.cfg.in b/lib/asan/lit_tests/Unit/lit.site.cfg.in index 315d24d1ed09..a45870c9b0e1 100644 --- a/lib/asan/lit_tests/Unit/lit.site.cfg.in +++ b/lib/asan/lit_tests/Unit/lit.site.cfg.in @@ -1,17 +1,16 @@ ## Autogenerated by LLVM/Clang configuration. # Do not edit! -config.target_triple = "@TARGET_TRIPLE@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@" -config.llvm_build_mode = "@LLVM_BUILD_MODE@" -config.asan_binary_dir = "@ASAN_BINARY_DIR@" +# Load common config for all compiler-rt unit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.unit.configured") -try: - config.llvm_build_mode = config.llvm_build_mode % lit.params -except KeyError,e: - key, = e.args - lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key)) +# Setup config name. +config.name = 'AddressSanitizer-Unit' -# Let the main config do the real work. -lit.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/Unit/lit.cfg") +# Setup test source and exec root. For unit tests, we define +# it as build directory with ASan unit tests. +config.test_exec_root = "@ASAN_BINARY_DIR@/tests" +config.test_source_root = config.test_exec_root + +if config.host_os == 'Linux': + config.environment['ASAN_OPTIONS'] = 'detect_leaks=1' diff --git a/lib/asan/lit_tests/deep_tail_call.cc b/lib/asan/lit_tests/deep_tail_call.cc deleted file mode 100644 index 6aa15e81f6ec..000000000000 --- a/lib/asan/lit_tests/deep_tail_call.cc +++ /dev/null @@ -1,24 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -// CHECK: AddressSanitizer: global-buffer-overflow -int global[10]; -// CHECK: {{#0.*call4}} -void __attribute__((noinline)) call4(int i) { global[i+10]++; } -// CHECK: {{#1.*call3}} -void __attribute__((noinline)) call3(int i) { call4(i); } -// CHECK: {{#2.*call2}} -void __attribute__((noinline)) call2(int i) { call3(i); } -// CHECK: {{#3.*call1}} -void __attribute__((noinline)) call1(int i) { call2(i); } -// CHECK: {{#4.*main}} -int main(int argc, char **argv) { - call1(argc); - return global[0]; -} diff --git a/lib/asan/lit_tests/double-free.cc b/lib/asan/lit_tests/double-free.cc deleted file mode 100644 index 9e201117c563..000000000000 --- a/lib/asan/lit_tests/double-free.cc +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -#include <stdlib.h> -#include <string.h> -int main(int argc, char **argv) { - char *x = (char*)malloc(10 * sizeof(char)); - memset(x, 0, 10); - int res = x[argc]; - free(x); - free(x + argc - 1); // BOOM - // CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0 - // CHECK: double-free.cc:[[@LINE-2]] - // CHECK: freed by thread T0 here: - // CHECK: double-free.cc:[[@LINE-5]] - // CHECK: allocated by thread T0 here: - // CHECK: double-free.cc:[[@LINE-10]] - return res; -} diff --git a/lib/asan/lit_tests/global-overflow.cc b/lib/asan/lit_tests/global-overflow.cc deleted file mode 100644 index 6a2f12e106fe..000000000000 --- a/lib/asan/lit_tests/global-overflow.cc +++ /dev/null @@ -1,25 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -#include <string.h> -int main(int argc, char **argv) { - static char XXX[10]; - static char YYY[10]; - static char ZZZ[10]; - memset(XXX, 0, 10); - memset(YYY, 0, 10); - memset(ZZZ, 0, 10); - int res = YYY[argc * 10]; // BOOOM - // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in _?main .*global-overflow.cc:}}[[@LINE-2]] - // CHECK: {{0x.* is located 0 bytes to the right of global variable}} - // CHECK: {{.*YYY.* of size 10}} - res += XXX[argc] + ZZZ[argc]; - return res; -} diff --git a/lib/asan/lit_tests/heap-overflow.cc b/lib/asan/lit_tests/heap-overflow.cc deleted file mode 100644 index f1d719cd0b20..000000000000 --- a/lib/asan/lit_tests/heap-overflow.cc +++ /dev/null @@ -1,36 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out - -#include <stdlib.h> -#include <string.h> -int main(int argc, char **argv) { - char *x = (char*)malloc(10 * sizeof(char)); - memset(x, 0, 10); - int res = x[argc * 10]; // BOOOM - // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in _?main .*heap-overflow.cc:}}[[@LINE-2]] - // CHECK: {{0x.* is located 0 bytes to the right of 10-byte region}} - // CHECK: {{allocated by thread T0 here:}} - - // CHECK-Linux: {{ #0 0x.* in .*malloc}} - // CHECK-Linux: {{ #1 0x.* in main .*heap-overflow.cc:21}} - - // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}} - // CHECK-Darwin: {{ #1 0x.* in _?main .*heap-overflow.cc:21}} - free(x); - return res; -} diff --git a/lib/asan/lit_tests/initialization-blacklist.cc b/lib/asan/lit_tests/initialization-blacklist.cc deleted file mode 100644 index 12fbc49ed91b..000000000000 --- a/lib/asan/lit_tests/initialization-blacklist.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Test for blacklist functionality of initialization-order checker. - -// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-blacklist-extra.cc\ -// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ -// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ -// RUN: -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-blacklist-extra.cc\ -// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ -// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ -// RUN: -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-blacklist-extra.cc\ -// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ -// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ -// RUN: -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-blacklist-extra.cc\ -// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ -// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ -// RUN: -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-blacklist-extra.cc\ -// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ -// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ -// RUN: -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-blacklist-extra.cc\ -// RUN: %p/Helpers/initialization-blacklist-extra2.cc \ -// RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt \ -// RUN: -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 - -// Function is defined in another TU. -int readBadGlobal(); -int x = readBadGlobal(); // init-order bug. - -// Function is defined in another TU. -int accessBadObject(); -int y = accessBadObject(); // init-order bug. - -int readBadSrcGlobal(); -int z = readBadSrcGlobal(); // init-order bug. - -int main(int argc, char **argv) { - return argc + x + y + z - 1; -} diff --git a/lib/asan/lit_tests/initialization-constexpr.cc b/lib/asan/lit_tests/initialization-constexpr.cc deleted file mode 100644 index ba5410674f76..000000000000 --- a/lib/asan/lit_tests/initialization-constexpr.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Constexpr: -// We need to check that a global variable initialized with a constexpr -// constructor can be accessed during dynamic initialization (as a constexpr -// constructor implies that it was initialized during constant initialization, -// not dynamic initialization). - -// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O1 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O2 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m64 -O3 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O1 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O2 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 -// RUN: %clangxx_asan -m32 -O3 %s %p/Helpers/initialization-constexpr-extra.cc\ -// RUN: --std=c++11 -fsanitize=init-order -o %t -// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 - -class Integer { - private: - int value; - - public: - constexpr Integer(int x = 0) : value(x) {} - int getValue() {return value;} -}; -Integer coolestInteger(42); -int getCoolestInteger() { return coolestInteger.getValue(); } - -int main() { return 0; } diff --git a/lib/asan/lit_tests/interface_test.cc b/lib/asan/lit_tests/interface_test.cc deleted file mode 100644 index 428a109fe70d..000000000000 --- a/lib/asan/lit_tests/interface_test.cc +++ /dev/null @@ -1,8 +0,0 @@ -// Check that user may include ASan interface header. -// RUN: %clang -fsanitize=address -I %p/../../../include %s -o %t && %t -// RUN: %clang -I %p/../../../include %s -o %t && %t -#include <sanitizer/asan_interface.h> - -int main() { - return 0; -} diff --git a/lib/asan/lit_tests/large_func_test.cc b/lib/asan/lit_tests/large_func_test.cc deleted file mode 100644 index ceecc29b7b0a..000000000000 --- a/lib/asan/lit_tests/large_func_test.cc +++ /dev/null @@ -1,63 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out - -#include <stdlib.h> -__attribute__((noinline)) -static void LargeFunction(int *x, int zero) { - x[0]++; - x[1]++; - x[2]++; - x[3]++; - x[4]++; - x[5]++; - x[6]++; - x[7]++; - x[8]++; - x[9]++; - - // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} - // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} - // CHECK: {{READ of size 4 at 0x.* thread T0}} - x[zero + 103]++; // we should report this exact line - // atos incorrectly extracts the symbol name for the static functions on - // Darwin. - // CHECK-Linux: {{#0 0x.* in LargeFunction.*large_func_test.cc:}}[[@LINE-3]] - // CHECK-Darwin: {{#0 0x.* in .*LargeFunction.*large_func_test.cc}}:[[@LINE-4]] - - x[10]++; - x[11]++; - x[12]++; - x[13]++; - x[14]++; - x[15]++; - x[16]++; - x[17]++; - x[18]++; - x[19]++; -} - -int main(int argc, char **argv) { - int *x = new int[100]; - LargeFunction(x, argc - 1); - // CHECK: {{ #1 0x.* in _?main .*large_func_test.cc:}}[[@LINE-1]] - // CHECK: {{0x.* is located 12 bytes to the right of 400-byte region}} - // CHECK: {{allocated by thread T0 here:}} - // CHECK-Linux: {{ #0 0x.* in operator new.*}} - // CHECK-Darwin: {{ #0 0x.* in .*_Zna.*}} - // CHECK: {{ #1 0x.* in _?main .*large_func_test.cc:}}[[@LINE-7]] - delete x; -} diff --git a/lib/asan/lit_tests/lit.cfg b/lib/asan/lit_tests/lit.cfg index 5daecd9e557d..71a700c6ac3b 100644 --- a/lib/asan/lit_tests/lit.cfg +++ b/lib/asan/lit_tests/lit.cfg @@ -2,24 +2,27 @@ import os +import lit.util + def get_required_attr(config, attr_name): attr_value = getattr(config, attr_name, None) if not attr_value: - lit.fatal("No attribute %r in test configuration! You may need to run " - "tests from your build directory or add this attribute " - "to lit.site.cfg " % attr_name) + lit_config.fatal( + "No attribute %r in test configuration! You may need to run " + "tests from your build directory or add this attribute " + "to lit.site.cfg " % attr_name) return attr_value # Setup config name. -config.name = 'AddressSanitizer' +config.name = 'AddressSanitizer' + config.bits # Setup source root. config.test_source_root = os.path.dirname(__file__) def DisplayNoConfigMessage(): - lit.fatal("No site specific configuration available! " + - "Try running your test from the build tree or running " + - "make check-asan") + lit_config.fatal("No site specific configuration available! " + + "Try running your test from the build tree or running " + + "make check-asan") # Figure out LLVM source root. llvm_src_root = getattr(config, 'llvm_src_root', None) @@ -27,9 +30,9 @@ if llvm_src_root is None: # We probably haven't loaded the site-specific configuration: the user # is likely trying to run a test file directly, and the site configuration # wasn't created by the build system. - asan_site_cfg = lit.params.get('asan_site_config', None) + asan_site_cfg = lit_config.params.get('asan_site_config', None) if (asan_site_cfg) and (os.path.exists(asan_site_cfg)): - lit.load_config(config, asan_site_cfg) + lit_config.load_config(config, asan_site_cfg) raise SystemExit # Try to guess the location of site-specific configuration using llvm-config @@ -45,51 +48,45 @@ if llvm_src_root is None: if (not asan_site_cfg) or (not os.path.exists(asan_site_cfg)): DisplayNoConfigMessage() - lit.load_config(config, asan_site_cfg) + lit_config.load_config(config, asan_site_cfg) raise SystemExit -# Setup attributes common for all compiler-rt projects. -compiler_rt_src_root = get_required_attr(config, "compiler_rt_src_root") -compiler_rt_lit_cfg = os.path.join(compiler_rt_src_root, "lib", - "lit.common.cfg") -if (not compiler_rt_lit_cfg) or (not os.path.exists(compiler_rt_lit_cfg)): - lit.fatal("Can't find common compiler-rt lit config at: %r" - % compiler_rt_lit_cfg) -lit.load_config(config, compiler_rt_lit_cfg) - # Setup default compiler flags used with -fsanitize=address option. # FIXME: Review the set of required flags and check if it can be reduced. -clang_asan_cxxflags = ("-ccc-cxx " - + "-fsanitize=address " - + "-mno-omit-leaf-frame-pointer " - + "-fno-omit-frame-pointer " - + "-fno-optimize-sibling-calls " - + "-g") +bits_cflag = " -m" + config.bits +clang_asan_cflags = (" -fsanitize=address" + + " -mno-omit-leaf-frame-pointer" + + " -fno-omit-frame-pointer" + + " -fno-optimize-sibling-calls" + + " -g" + + bits_cflag) +clang_asan_cxxflags = " --driver-mode=g++" + clang_asan_cflags +config.substitutions.append( ("%clang ", " " + config.clang + bits_cflag + " ")) +config.substitutions.append( ("%clangxx ", (" " + config.clang + + " --driver-mode=g++" + + bits_cflag + " ")) ) +config.substitutions.append( ("%clang_asan ", (" " + config.clang + " " + + clang_asan_cflags + " ")) ) config.substitutions.append( ("%clangxx_asan ", (" " + config.clang + " " + clang_asan_cxxflags + " ")) ) -# Setup path to external LLVM symbolizer to run AddressSanitizer output tests. -llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) -if llvm_tools_dir: - config.environment['LLVM_SYMBOLIZER_PATH'] = os.path.join( - llvm_tools_dir, "llvm-symbolizer") - -# Setup path to symbolizer script. -# FIXME: Instead we should copy this script to the build tree and point -# at it there. -asan_source_dir = os.path.join(config.test_source_root, "..") -symbolizer = os.path.join(asan_source_dir, - 'scripts', 'asan_symbolize.py') -if not os.path.exists(symbolizer): - lit.fatal("Can't find symbolizer script on path %r" % symbolizer) -# Define %symbolize substitution that filters output through -# symbolizer and c++filt (for demangling). -config.substitutions.append( ("%symbolize ", (" " + symbolizer + - " | c++filt " ))) +# Setup path to asan_symbolize.py script. +asan_source_dir = get_required_attr(config, "asan_source_dir") +asan_symbolize = os.path.join(asan_source_dir, "scripts", "asan_symbolize.py") +if not os.path.exists(asan_symbolize): + lit_config.fatal("Can't find script on path %r" % asan_symbolize) +python_exec = get_required_attr(config, "python_executable") +config.substitutions.append( ("%asan_symbolize", python_exec + " " + asan_symbolize + " ") ) # Define CHECK-%os to check for OS-dependent output. config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os))) +config.available_features.add("asan-" + config.bits + "-bits") + +# Turn on leak detection on 64-bit Linux. +if config.host_os == 'Linux' and config.bits == '64': + config.environment['ASAN_OPTIONS'] = 'detect_leaks=1' + # Default test suffixes. config.suffixes = ['.c', '.cc', '.cpp'] diff --git a/lib/asan/lit_tests/lit.site.cfg.in b/lib/asan/lit_tests/lit.site.cfg.in deleted file mode 100644 index 08546cdabe02..000000000000 --- a/lib/asan/lit_tests/lit.site.cfg.in +++ /dev/null @@ -1,22 +0,0 @@ -## Autogenerated by LLVM/Clang configuration. -# Do not edit! - -config.target_triple = "@TARGET_TRIPLE@" -config.host_os = "@HOST_OS@" -config.llvm_src_root = "@LLVM_SOURCE_DIR@" -config.llvm_obj_root = "@LLVM_BINARY_DIR@" -config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@" -config.llvm_tools_dir = "@LLVM_TOOLS_DIR@" -config.clang = "@LLVM_BINARY_DIR@/bin/clang" -config.compiler_rt_arch = "@COMPILER_RT_SUPPORTED_ARCH@" - -# LLVM tools dir can be passed in lit parameters, so try to -# apply substitution. -try: - config.llvm_tools_dir = config.llvm_tools_dir % lit.params -except KeyError,e: - key, = e.args - lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key, key)) - -# Let the main config do the real work. -lit.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/lit.cfg") diff --git a/lib/asan/lit_tests/memcmp_strict_test.cc b/lib/asan/lit_tests/memcmp_strict_test.cc deleted file mode 100644 index 00bf921c744a..000000000000 --- a/lib/asan/lit_tests/memcmp_strict_test.cc +++ /dev/null @@ -1,16 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && ASAN_OPTIONS=strict_memcmp=0 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-nonstrict -// RUN: %clangxx_asan -m64 -O0 %s -o %t && ASAN_OPTIONS=strict_memcmp=1 %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-strict -// Default to strict_memcmp=1. -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s --check-prefix=CHECK-strict - -#include <stdio.h> -#include <string.h> -int main() { - char kFoo[] = "foo"; - char kFubar[] = "fubar"; - int res = memcmp(kFoo, kFubar, strlen(kFubar)); - printf("res: %d\n", res); - // CHECK-nonstrict: {{res: -1}} - // CHECK-strict: AddressSanitizer: stack-buffer-overflow - return 0; -} diff --git a/lib/asan/lit_tests/memcmp_test.cc b/lib/asan/lit_tests/memcmp_test.cc deleted file mode 100644 index ac3f7f32ea75..000000000000 --- a/lib/asan/lit_tests/memcmp_test.cc +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -#include <string.h> -int main(int argc, char **argv) { - char a1[] = {argc, 2, 3, 4}; - char a2[] = {1, 2*argc, 3, 4}; - int res = memcmp(a1, a2, 4 + argc); // BOOM - // CHECK: AddressSanitizer: stack-buffer-overflow - // CHECK: {{#0.*memcmp}} - // CHECK: {{#1.*main}} - return res; -} diff --git a/lib/asan/lit_tests/null_deref.cc b/lib/asan/lit_tests/null_deref.cc deleted file mode 100644 index 60a521d1c210..000000000000 --- a/lib/asan/lit_tests/null_deref.cc +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out - -__attribute__((noinline)) -static void NullDeref(int *ptr) { - // CHECK: ERROR: AddressSanitizer: SEGV on unknown address - // CHECK: {{0x0*00028 .*pc 0x.*}} - // CHECK: {{AddressSanitizer can not provide additional info.}} - ptr[10]++; // BOOM - // atos on Mac cannot extract the symbol name correctly. - // CHECK-Linux: {{ #0 0x.* in NullDeref.*null_deref.cc:}}[[@LINE-2]] - // CHECK-Darwin: {{ #0 0x.* in .*NullDeref.*null_deref.cc:}}[[@LINE-3]] -} -int main() { - NullDeref((int*)0); - // CHECK: {{ #1 0x.* in _?main.*null_deref.cc:}}[[@LINE-1]] -} diff --git a/lib/asan/lit_tests/partial_right.cc b/lib/asan/lit_tests/partial_right.cc deleted file mode 100644 index c579262726f9..000000000000 --- a/lib/asan/lit_tests/partial_right.cc +++ /dev/null @@ -1,17 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -#include <stdlib.h> -int main(int argc, char **argv) { - volatile int *x = (int*)malloc(2*sizeof(int) + 2); - int res = x[2]; // BOOOM - // CHECK: {{READ of size 4 at 0x.* thread T0}} - // CHECK: [[ADDR:0x[01-9a-fa-f]+]] is located 0 bytes to the right of {{.*}}-byte region [{{.*}},{{.*}}[[ADDR]]) - return res; -} diff --git a/lib/asan/lit_tests/shared-lib-test.cc b/lib/asan/lit_tests/shared-lib-test.cc deleted file mode 100644 index 05bf3ecdf4f9..000000000000 --- a/lib/asan/lit_tests/shared-lib-test.cc +++ /dev/null @@ -1,54 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %p/SharedLibs/shared-lib-test-so.cc \ -// RUN: -fPIC -shared -o %t-so.so -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -#include <dlfcn.h> -#include <stdio.h> -#include <string.h> - -#include <string> - -using std::string; - -typedef void (fun_t)(int x); - -int main(int argc, char *argv[]) { - string path = string(argv[0]) + "-so.so"; - printf("opening %s ... \n", path.c_str()); - void *lib = dlopen(path.c_str(), RTLD_NOW); - if (!lib) { - printf("error in dlopen(): %s\n", dlerror()); - return 1; - } - fun_t *inc = (fun_t*)dlsym(lib, "inc"); - if (!inc) return 1; - printf("ok\n"); - inc(1); - inc(-1); // BOOM - // CHECK: {{.*ERROR: AddressSanitizer: global-buffer-overflow}} - // CHECK: {{READ of size 4 at 0x.* thread T0}} - // CHECK: {{ #0 0x.*}} - // CHECK: {{ #1 0x.* in _?main .*shared-lib-test.cc:}}[[@LINE-4]] - return 0; -} diff --git a/lib/asan/lit_tests/stack-overflow.cc b/lib/asan/lit_tests/stack-overflow.cc deleted file mode 100644 index 25ea43af48a4..000000000000 --- a/lib/asan/lit_tests/stack-overflow.cc +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -#include <string.h> -int main(int argc, char **argv) { - char x[10]; - memset(x, 0, 10); - int res = x[argc * 10]; // BOOOM - // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in _?main .*stack-overflow.cc:}}[[@LINE-2]] - // CHECK: {{Address 0x.* is located in stack of thread T0 at offset}} - // CHECK-NEXT: in{{.*}}main{{.*}}stack-overflow.cc - return res; -} diff --git a/lib/asan/lit_tests/stack-use-after-return.cc b/lib/asan/lit_tests/stack-use-after-return.cc deleted file mode 100644 index f8d8a1a2ae39..000000000000 --- a/lib/asan/lit_tests/stack-use-after-return.cc +++ /dev/null @@ -1,45 +0,0 @@ -// XFAIL: * -// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O0 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O1 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O2 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m64 -O3 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m32 -O0 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m32 -O1 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m32 -O2 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -fsanitize=use-after-return -m32 -O3 %s -o %t && \ -// RUN: %t 2>&1 | %symbolize | FileCheck %s - -#include <stdio.h> - -__attribute__((noinline)) -char *Ident(char *x) { - fprintf(stderr, "1: %p\n", x); - return x; -} - -__attribute__((noinline)) -char *Func1() { - char local; - return Ident(&local); -} - -__attribute__((noinline)) -void Func2(char *x) { - fprintf(stderr, "2: %p\n", x); - *x = 1; - // CHECK: WRITE of size 1 {{.*}} thread T0 - // CHECK: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-2]] - // CHECK: is located {{.*}} in frame <{{.*}}Func1{{.*}}> of T0's stack -} - -int main(int argc, char **argv) { - Func2(Func1()); - return 0; -} diff --git a/lib/asan/lit_tests/strncpy-overflow.cc b/lib/asan/lit_tests/strncpy-overflow.cc deleted file mode 100644 index 5133b5c1653e..000000000000 --- a/lib/asan/lit_tests/strncpy-overflow.cc +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out - -#include <string.h> -#include <stdlib.h> -int main(int argc, char **argv) { - char *hello = (char*)malloc(6); - strcpy(hello, "hello"); - char *short_buffer = (char*)malloc(9); - strncpy(short_buffer, hello, 10); // BOOM - // CHECK: {{WRITE of size 10 at 0x.* thread T0}} - // CHECK-Linux: {{ #0 0x.* in .*strncpy}} - // CHECK-Darwin: {{ #0 0x.* in _?wrap_strncpy}} - // CHECK: {{ #1 0x.* in _?main .*strncpy-overflow.cc:}}[[@LINE-4]] - // CHECK: {{0x.* is located 0 bytes to the right of 9-byte region}} - // CHECK: {{allocated by thread T0 here:}} - - // CHECK-Linux: {{ #0 0x.* in .*malloc}} - // CHECK-Linux: {{ #1 0x.* in main .*strncpy-overflow.cc:}}[[@LINE-10]] - - // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}} - // CHECK-Darwin: {{ #1 0x.* in _?main .*strncpy-overflow.cc:}}[[@LINE-13]] - return short_buffer[8]; -} diff --git a/lib/asan/lit_tests/use-after-free-right.cc b/lib/asan/lit_tests/use-after-free-right.cc deleted file mode 100644 index b0de07b04a08..000000000000 --- a/lib/asan/lit_tests/use-after-free-right.cc +++ /dev/null @@ -1,46 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out - -// Test use-after-free report in the case when access is at the right border of -// the allocation. - -#include <stdlib.h> -int main() { - volatile char *x = (char*)malloc(sizeof(char)); - free((void*)x); - *x = 42; - // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} - // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} - // CHECK: {{WRITE of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in _?main .*use-after-free-right.cc:25}} - // CHECK: {{0x.* is located 0 bytes inside of 1-byte region .0x.*,0x.*}} - // CHECK: {{freed by thread T0 here:}} - - // CHECK-Linux: {{ #0 0x.* in .*free}} - // CHECK-Linux: {{ #1 0x.* in main .*use-after-free-right.cc:24}} - - // CHECK-Darwin: {{ #0 0x.* in _?wrap_free}} - // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free-right.cc:24}} - - // CHECK: {{previously allocated by thread T0 here:}} - - // CHECK-Linux: {{ #0 0x.* in .*malloc}} - // CHECK-Linux: {{ #1 0x.* in main .*use-after-free-right.cc:23}} - - // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}} - // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free-right.cc:23}} -} diff --git a/lib/asan/lit_tests/use-after-free.cc b/lib/asan/lit_tests/use-after-free.cc deleted file mode 100644 index aee185dc4518..000000000000 --- a/lib/asan/lit_tests/use-after-free.cc +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-%os < %t.out - -#include <stdlib.h> -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return x[5]; - // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} - // CHECK: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} - // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in _?main .*use-after-free.cc:22}} - // CHECK: {{0x.* is located 5 bytes inside of 10-byte region .0x.*,0x.*}} - // CHECK: {{freed by thread T0 here:}} - - // CHECK-Linux: {{ #0 0x.* in .*free}} - // CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:21}} - - // CHECK-Darwin: {{ #0 0x.* in _?wrap_free}} - // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free.cc:21}} - - // CHECK: {{previously allocated by thread T0 here:}} - - // CHECK-Linux: {{ #0 0x.* in .*malloc}} - // CHECK-Linux: {{ #1 0x.* in main .*use-after-free.cc:20}} - - // CHECK-Darwin: {{ #0 0x.* in _?wrap_malloc.*}} - // CHECK-Darwin: {{ #1 0x.* in _?main .*use-after-free.cc:20}} -} diff --git a/lib/asan/lit_tests/wait.cc b/lib/asan/lit_tests/wait.cc deleted file mode 100644 index 88fbb17176fa..000000000000 --- a/lib/asan/lit_tests/wait.cc +++ /dev/null @@ -1,77 +0,0 @@ -// RUN: %clangxx_asan -DWAIT -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -// RUN: %clangxx_asan -DWAITPID -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAITPID -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAITPID -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAITPID -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -// RUN: %clangxx_asan -DWAITID -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAITID -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAITID -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAITID -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -// RUN: %clangxx_asan -DWAIT3 -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT3 -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT3 -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT3 -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -// RUN: %clangxx_asan -DWAIT4 -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT4 -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT4 -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT4 -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -// RUN: %clangxx_asan -DWAIT3_RUSAGE -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT3_RUSAGE -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT3_RUSAGE -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT3_RUSAGE -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - -// RUN: %clangxx_asan -DWAIT4_RUSAGE -m64 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT4_RUSAGE -m64 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT4_RUSAGE -m32 -O0 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s -// RUN: %clangxx_asan -DWAIT4_RUSAGE -m32 -O3 %s -o %t && %t 2>&1 | %symbolize | FileCheck %s - - -#include <assert.h> -#include <sys/wait.h> -#include <unistd.h> - -int main(int argc, char **argv) { - pid_t pid = fork(); - if (pid) { // parent - int x[3]; - int *status = x + argc * 3; - int res; -#if defined(WAIT) - res = wait(status); -#elif defined(WAITPID) - res = waitpid(pid, status, WNOHANG); -#elif defined(WAITID) - siginfo_t *si = (siginfo_t*)(x + argc * 3); - res = waitid(P_ALL, 0, si, WEXITED | WNOHANG); -#elif defined(WAIT3) - res = wait3(status, WNOHANG, NULL); -#elif defined(WAIT4) - res = wait4(pid, status, WNOHANG, NULL); -#elif defined(WAIT3_RUSAGE) || defined(WAIT4_RUSAGE) - struct rusage *ru = (struct rusage*)(x + argc * 3); - int good_status; -# if defined(WAIT3_RUSAGE) - res = wait3(&good_status, WNOHANG, ru); -# elif defined(WAIT4_RUSAGE) - res = wait4(pid, &good_status, WNOHANG, ru); -# endif -#endif - // CHECK: stack-buffer-overflow - // CHECK: {{WRITE of size .* at 0x.* thread T0}} - // CHECK: {{in .*wait}} - // CHECK: {{in _?main .*wait.cc:}} - // CHECK: is located in stack of thread T0 at offset - // CHECK: {{in _?main}} - return res != -1; - } - // child - return 0; -} |