Index: Linux/glob.cc =================================================================== --- Linux/glob.cc +++ Linux/glob.cc @@ -1,33 +0,0 @@ -// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 -// XFAIL: android -// -// RUN: %clangxx_asan -O0 %s -o %t && %run %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -o %t && %run %t %p 2>&1 | FileCheck %s -// XFAIL: arm-linux-gnueabi - -#include -#include -#include -#include -#include -#include - - -int main(int argc, char *argv[]) { - std::string path = argv[1]; - std::string pattern = path + "/glob_test_root/*a"; - printf("pattern: %s\n", pattern.c_str()); - - glob_t globbuf; - int res = glob(pattern.c_str(), 0, 0, &globbuf); - - printf("%d %s\n", errno, strerror(errno)); - assert(res == 0); - 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; -} Index: Linux/heap-overflow-large.cc =================================================================== --- Linux/heap-overflow-large.cc +++ Linux/heap-overflow-large.cc @@ -1,23 +0,0 @@ -// Regression test for -// https://code.google.com/p/address-sanitizer/issues/detail?id=183 - -// RUN: %clangxx_asan -O2 %s -o %t -// RUN: not %run %t 12 2>&1 | FileCheck %s -// RUN: not %run %t 100 2>&1 | FileCheck %s -// RUN: not %run %t 10000 2>&1 | FileCheck %s - -#include -#include -#include - -int main(int argc, char *argv[]) { - fprintf(stderr, "main\n"); - int *x = new int[5]; - memset(x, 0, sizeof(x[0]) * 5); - int index = atoi(argv[1]); - int res = x[index]; - // CHECK: main - // CHECK-NOT: CHECK failed - delete[] x; - return res ? res : 1; -} Index: Linux/heavy_uar_test.cc =================================================================== --- Linux/heavy_uar_test.cc +++ Linux/heavy_uar_test.cc @@ -1,59 +0,0 @@ -// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 -// RUN: %clangxx_asan -O0 %s -o %t && \ -// RUN: not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O2 %s -o %t && \ -// RUN: not %run %t 2>&1 | FileCheck %s -// XFAIL: arm-linux-gnueabi - -// FIXME: Fix this test under GCC. -// REQUIRES: Clang -// XFAIL: armv7l-unknown-linux-gnueabihf - -#include -#include -#include - -__attribute__((noinline)) -char *pretend_to_do_something(char *x) { - __asm__ __volatile__("" : : "r" (x) : "memory"); - return x; -} - -__attribute__((noinline)) -char *LeakStack() { - char x[1024]; - memset(x, 0, sizeof(x)); - return pretend_to_do_something(x); -} - -template -__attribute__((noinline)) -void RecuriveFunctionWithStackFrame(int depth) { - if (depth <= 0) return; - char x[kFrameSize]; - x[0] = depth; - pretend_to_do_something(x); - RecuriveFunctionWithStackFrame(depth - 1); -} - -int main(int argc, char **argv) { - int n_iter = argc >= 2 ? atoi(argv[1]) : 1000; - int depth = argc >= 3 ? atoi(argv[2]) : 500; - for (int i = 0; i < n_iter; i++) { - RecuriveFunctionWithStackFrame<10>(depth); - RecuriveFunctionWithStackFrame<100>(depth); - RecuriveFunctionWithStackFrame<500>(depth); - RecuriveFunctionWithStackFrame<1024>(depth); - RecuriveFunctionWithStackFrame<2000>(depth); - RecuriveFunctionWithStackFrame<5000>(depth); - RecuriveFunctionWithStackFrame<10000>(depth); - } - char *stale_stack = LeakStack(); - RecuriveFunctionWithStackFrame<1024>(10); - stale_stack[100]++; - // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address - // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame - // CHECK: in LeakStack(){{.*}}heavy_uar_test.cc: - // CHECK: [{{16|32}}, {{1040|1056}}) 'x' - return 0; -} Index: Linux/interception_failure_test.cc =================================================================== --- Linux/interception_failure_test.cc +++ Linux/interception_failure_test.cc @@ -1,22 +0,0 @@ -// If user provides his own libc functions, ASan doesn't -// intercept these functions. - -// RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s -#include -#include - -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 -} Index: Linux/new_array_cookie_test.cc =================================================================== --- Linux/new_array_cookie_test.cc +++ Linux/new_array_cookie_test.cc @@ -1,24 +0,0 @@ -// REQUIRES: asan-64-bits -// RUN: %clangxx_asan -O3 %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE -#include -#include -struct C { - int x; - ~C() { - fprintf(stderr, "ZZZZZZZZ\n"); - exit(1); - } -}; - -int main(int argc, char **argv) { - C *buffer = new C[argc]; - buffer[-2].x = 10; -// CHECK: AddressSanitizer: heap-buffer-overflow -// CHECK: in main {{.*}}new_array_cookie_test.cc:[[@LINE-2]] -// CHECK: is located 0 bytes inside of 12-byte region -// NO_COOKIE: ZZZZZZZZ - delete [] buffer; -} Index: Linux/new_array_cookie_uaf_test.cc =================================================================== --- Linux/new_array_cookie_uaf_test.cc +++ Linux/new_array_cookie_uaf_test.cc @@ -1,38 +0,0 @@ -// REQUIRES: asan-64-bits -// RUN: %clangxx_asan -O3 %s -o %t -// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s --check-prefix=COOKIE -// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE -#include -#include -#include -int dtor_counter; -struct C { - int x; - ~C() { - dtor_counter++; - fprintf(stderr, "DTOR %d\n", dtor_counter); - } -}; - -__attribute__((noinline)) void Delete(C *c) { delete[] c; } -__attribute__((no_sanitize_address)) void Write42ToCookie(C *c) { - long *p = reinterpret_cast(c); - p[-1] = 42; -} - -int main(int argc, char **argv) { - C *buffer = new C[argc]; - delete [] buffer; - Write42ToCookie(buffer); - delete [] buffer; -// COOKIE: DTOR 1 -// COOKIE-NOT: DTOR 2 -// COOKIE: AddressSanitizer: loaded array cookie from free-d memory -// COOKIE: AddressSanitizer: attempting double-free -// NO_COOKIE: DTOR 1 -// NO_COOKIE: DTOR 43 -// NO_COOKIE-NOT: DTOR 44 -// NO_COOKIE-NOT: AddressSanitizer: loaded array cookie from free-d memory -// NO_COOKIE: AddressSanitizer: attempting double-free - -} Index: Linux/new_array_cookie_with_new_from_class.cc =================================================================== --- Linux/new_array_cookie_with_new_from_class.cc +++ Linux/new_array_cookie_with_new_from_class.cc @@ -1,38 +0,0 @@ -// Test that we do not poison the array cookie if the operator new is defined -// inside the class. -// RUN: %clangxx_asan %s -o %t && %run %t -// -// XFAIL: android -// XFAIL: armv7l-unknown-linux-gnueabihf -#include -#include -#include -#include -#include -struct Foo { - void *operator new(size_t s) { return Allocate(s); } - void *operator new[] (size_t s) { return Allocate(s); } - ~Foo(); - static void *allocated; - static void *Allocate(size_t s) { - assert(!allocated); - return allocated = ::new char[s]; - } -}; - -Foo::~Foo() {} -void *Foo::allocated; - -Foo *getFoo(size_t n) { - return new Foo[n]; -} - -int main() { - Foo *foo = getFoo(10); - fprintf(stderr, "foo : %p\n", foo); - fprintf(stderr, "alloc: %p\n", Foo::allocated); - assert(reinterpret_cast(foo) == - reinterpret_cast(Foo::allocated) + sizeof(void*)); - *reinterpret_cast(Foo::allocated) = 42; - return 0; -} Index: Linux/tsd_dtor_leak.cc =================================================================== --- Linux/tsd_dtor_leak.cc +++ Linux/tsd_dtor_leak.cc @@ -1,39 +0,0 @@ -// Regression test for a leak in tsd: -// https://code.google.com/p/address-sanitizer/issues/detail?id=233 -// RUN: %clangxx_asan -O1 %s -pthread -o %t -// RUN: ASAN_OPTIONS=quarantine_size=1 %run %t -#include -#include -#include -#include -#include - -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 = __sanitizer_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; - } -} Index: Posix/glob.cc =================================================================== --- Posix/glob.cc +++ Posix/glob.cc @@ -0,0 +1,33 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// XFAIL: android +// +// RUN: %clangxx_asan -O0 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// XFAIL: arm-linux-gnueabi + +#include +#include +#include +#include +#include +#include + + +int main(int argc, char *argv[]) { + std::string path = argv[1]; + std::string pattern = path + "/glob_test_root/*a"; + printf("pattern: %s\n", pattern.c_str()); + + glob_t globbuf; + int res = glob(pattern.c_str(), 0, 0, &globbuf); + + printf("%d %s\n", errno, strerror(errno)); + assert(res == 0); + 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; +} Index: Posix/new_array_cookie_test.cc =================================================================== --- Posix/new_array_cookie_test.cc +++ Posix/new_array_cookie_test.cc @@ -0,0 +1,24 @@ +// REQUIRES: asan-64-bits +// RUN: %clangxx_asan -O3 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s +// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE +#include +#include +struct C { + int x; + ~C() { + fprintf(stderr, "ZZZZZZZZ\n"); + exit(1); + } +}; + +int main(int argc, char **argv) { + C *buffer = new C[argc]; + buffer[-2].x = 10; +// CHECK: AddressSanitizer: heap-buffer-overflow +// CHECK: in main {{.*}}new_array_cookie_test.cc:[[@LINE-2]] +// CHECK: is located 0 bytes inside of 12-byte region +// NO_COOKIE: ZZZZZZZZ + delete [] buffer; +} Index: Posix/new_array_cookie_uaf_test.cc =================================================================== --- Posix/new_array_cookie_uaf_test.cc +++ Posix/new_array_cookie_uaf_test.cc @@ -0,0 +1,38 @@ +// REQUIRES: asan-64-bits +// RUN: %clangxx_asan -O3 %s -o %t +// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s --check-prefix=COOKIE +// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE +#include +#include +#include +int dtor_counter; +struct C { + int x; + ~C() { + dtor_counter++; + fprintf(stderr, "DTOR %d\n", dtor_counter); + } +}; + +__attribute__((noinline)) void Delete(C *c) { delete[] c; } +__attribute__((no_sanitize_address)) void Write42ToCookie(C *c) { + long *p = reinterpret_cast(c); + p[-1] = 42; +} + +int main(int argc, char **argv) { + C *buffer = new C[argc]; + delete [] buffer; + Write42ToCookie(buffer); + delete [] buffer; +// COOKIE: DTOR 1 +// COOKIE-NOT: DTOR 2 +// COOKIE: AddressSanitizer: loaded array cookie from free-d memory +// COOKIE: AddressSanitizer: attempting double-free +// NO_COOKIE: DTOR 1 +// NO_COOKIE: DTOR 43 +// NO_COOKIE-NOT: DTOR 44 +// NO_COOKIE-NOT: AddressSanitizer: loaded array cookie from free-d memory +// NO_COOKIE: AddressSanitizer: attempting double-free + +} Index: Posix/new_array_cookie_with_new_from_class.cc =================================================================== --- Posix/new_array_cookie_with_new_from_class.cc +++ Posix/new_array_cookie_with_new_from_class.cc @@ -0,0 +1,38 @@ +// Test that we do not poison the array cookie if the operator new is defined +// inside the class. +// RUN: %clangxx_asan %s -o %t && %run %t +// +// XFAIL: android +// XFAIL: armv7l-unknown-linux-gnueabihf +#include +#include +#include +#include +#include +struct Foo { + void *operator new(size_t s) { return Allocate(s); } + void *operator new[] (size_t s) { return Allocate(s); } + ~Foo(); + static void *allocated; + static void *Allocate(size_t s) { + assert(!allocated); + return allocated = ::new char[s]; + } +}; + +Foo::~Foo() {} +void *Foo::allocated; + +Foo *getFoo(size_t n) { + return new Foo[n]; +} + +int main() { + Foo *foo = getFoo(10); + fprintf(stderr, "foo : %p\n", foo); + fprintf(stderr, "alloc: %p\n", Foo::allocated); + assert(reinterpret_cast(foo) == + reinterpret_cast(Foo::allocated) + sizeof(void*)); + *reinterpret_cast(Foo::allocated) = 42; + return 0; +} Index: Posix/tsd_dtor_leak.cc =================================================================== --- Posix/tsd_dtor_leak.cc +++ Posix/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 -pthread -o %t +// RUN: ASAN_OPTIONS=quarantine_size=1 %run %t +#include +#include +#include +#include +#include + +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 = __sanitizer_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; + } +} Index: heap-overflow-large.cc =================================================================== --- heap-overflow-large.cc +++ 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 %run %t 12 2>&1 | FileCheck %s +// RUN: not %run %t 100 2>&1 | FileCheck %s +// RUN: not %run %t 10000 2>&1 | FileCheck %s + +#include +#include +#include + +int main(int argc, char *argv[]) { + fprintf(stderr, "main\n"); + int *x = new int[5]; + memset(x, 0, sizeof(x[0]) * 5); + int index = atoi(argv[1]); + int res = x[index]; + // CHECK: main + // CHECK-NOT: CHECK failed + delete[] x; + return res ? res : 1; +} Index: heavy_uar_test.cc =================================================================== --- heavy_uar_test.cc +++ heavy_uar_test.cc @@ -0,0 +1,59 @@ +// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: %clangxx_asan -O0 %s -o %t && \ +// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && \ +// RUN: not %run %t 2>&1 | FileCheck %s +// XFAIL: arm-linux-gnueabi + +// FIXME: Fix this test under GCC. +// REQUIRES: Clang +// XFAIL: armv7l-unknown-linux-gnueabihf + +#include +#include +#include + +__attribute__((noinline)) +char *pretend_to_do_something(char *x) { + __asm__ __volatile__("" : : "r" (x) : "memory"); + return x; +} + +__attribute__((noinline)) +char *LeakStack() { + char x[1024]; + memset(x, 0, sizeof(x)); + return pretend_to_do_something(x); +} + +template +__attribute__((noinline)) +void RecuriveFunctionWithStackFrame(int depth) { + if (depth <= 0) return; + char x[kFrameSize]; + x[0] = depth; + pretend_to_do_something(x); + RecuriveFunctionWithStackFrame(depth - 1); +} + +int main(int argc, char **argv) { + int n_iter = argc >= 2 ? atoi(argv[1]) : 1000; + int depth = argc >= 3 ? atoi(argv[2]) : 500; + for (int i = 0; i < n_iter; i++) { + RecuriveFunctionWithStackFrame<10>(depth); + RecuriveFunctionWithStackFrame<100>(depth); + RecuriveFunctionWithStackFrame<500>(depth); + RecuriveFunctionWithStackFrame<1024>(depth); + RecuriveFunctionWithStackFrame<2000>(depth); + RecuriveFunctionWithStackFrame<5000>(depth); + RecuriveFunctionWithStackFrame<10000>(depth); + } + char *stale_stack = LeakStack(); + RecuriveFunctionWithStackFrame<1024>(10); + stale_stack[100]++; + // CHECK: ERROR: AddressSanitizer: stack-use-after-return on address + // CHECK: is located in stack of thread T0 at offset {{116|132}} in frame + // CHECK: in LeakStack(){{.*}}heavy_uar_test.cc: + // CHECK: [{{16|32}}, {{1040|1056}}) 'x' + return 0; +} Index: interception_failure_test.cc =================================================================== --- interception_failure_test.cc +++ 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 && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s +#include +#include + +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 +}