diff options
Diffstat (limited to 'test/asan/TestCases/Posix')
38 files changed, 1056 insertions, 67 deletions
diff --git a/test/asan/TestCases/Posix/allow_user_segv.cc b/test/asan/TestCases/Posix/allow_user_segv.cc index b299ae8cb21e..69c1df9a1d3f 100644 --- a/test/asan/TestCases/Posix/allow_user_segv.cc +++ b/test/asan/TestCases/Posix/allow_user_segv.cc @@ -1,8 +1,8 @@ // Regression test for // https://code.google.com/p/address-sanitizer/issues/detail?id=180 -// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O2 %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && %env_asan_opts=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s #include <signal.h> #include <stdio.h> @@ -55,5 +55,5 @@ int main() { // CHECK: User sigaction installed // CHECK-NEXT: User sigaction called -// CHECK-NEXT: ASAN:SIGSEGV +// CHECK-NEXT: ASAN:DEADLYSIGNAL // CHECK: AddressSanitizer: SEGV on unknown address diff --git a/test/asan/TestCases/Posix/asan-symbolize-bad-path.cc b/test/asan/TestCases/Posix/asan-symbolize-bad-path.cc new file mode 100644 index 000000000000..22c03e8ddced --- /dev/null +++ b/test/asan/TestCases/Posix/asan-symbolize-bad-path.cc @@ -0,0 +1,4 @@ +// Test that asan_symbolize does not hang when provided with an non-existing +// path. +// RUN: echo '#0 0xabcdabcd (%T/bad/path+0x1234)' | %asan_symbolize | FileCheck %s +// CHECK: #0 0xabcdabcd diff --git a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc index 043130f9e549..dd59e4a60774 100644 --- a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc +++ b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc @@ -6,7 +6,7 @@ // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so // RUN: %clangxx_asan -O0 %s %libdl -o %t -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:symbolize=0 not %run %t 2>&1 | %asan_symbolize | FileCheck %s +// RUN: %env_asan_opts=symbolize=0 not %run %t 2>&1 | %asan_symbolize | FileCheck %s // XFAIL: arm-linux-gnueabi // XFAIL: armv7l-unknown-linux-gnueabihf diff --git a/test/asan/TestCases/Posix/assign_large_valloc_to_global.cc b/test/asan/TestCases/Posix/assign_large_valloc_to_global.cc index ad547ce0ce1b..8031d04aae48 100644 --- a/test/asan/TestCases/Posix/assign_large_valloc_to_global.cc +++ b/test/asan/TestCases/Posix/assign_large_valloc_to_global.cc @@ -2,8 +2,5 @@ // RUN: %clangxx_asan -O3 %s -o %t && %run %t #include <stdlib.h> #include <unistd.h> -#if !defined(__APPLE__) && !defined(__FreeBSD__) -# include <malloc.h> -#endif // !__APPLE__ && !__FreeBSD__ -int *p = (int*)valloc(1 << 20); -int main() { } +int *p; +int main() { posix_memalign((void **)&p, 4096, 1 << 20); } diff --git a/test/asan/TestCases/Posix/closed-fds.cc b/test/asan/TestCases/Posix/closed-fds.cc new file mode 100644 index 000000000000..3bbe3d8e68e1 --- /dev/null +++ b/test/asan/TestCases/Posix/closed-fds.cc @@ -0,0 +1,33 @@ +// Check that when the program closed its std(in|out|err), running the external +// symbolizer still works. + +// RUN: rm -f %t.log.* +// RUN: %clangxx_asan -O0 %s -o %t 2>&1 && %env_asan_opts=log_path=%t.log:verbosity=2 not %run %t 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK-FILE < %t.log.* + +// FIXME: copy %t.log back from the device and re-enable on Android. +// UNSUPPORTED: android + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int main(int argc, char **argv) { + int result = fprintf(stderr, "Closing streams.\n"); + assert(result > 0); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + result = fprintf(stderr, "Can you hear me now?\n"); + assert(result < 0); + char *x = (char *)malloc(10 * sizeof(char)); + free(x); + x[argc] = 'X'; // BOOM + // CHECK-FILE: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK-FILE: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} + // CHECK-FILE: {{WRITE of size 1 at 0x.* thread T0}} + // CHECK-FILE: {{ #0 0x.* in main .*closed-fds.cc:}}[[@LINE-4]] + return 0; +} diff --git a/test/asan/TestCases/Posix/coverage-caller-callee.cc b/test/asan/TestCases/Posix/coverage-caller-callee.cc new file mode 100644 index 000000000000..fb8b9bf92af2 --- /dev/null +++ b/test/asan/TestCases/Posix/coverage-caller-callee.cc @@ -0,0 +1,75 @@ +// Test caller-callee coverage with large number of threads +// and various numbers of callers and callees. + +// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 10 1 2>&1 | FileCheck %s --check-prefix=CHECK-10-1 +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 9 2 2>&1 | FileCheck %s --check-prefix=CHECK-9-2 +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 7 3 2>&1 | FileCheck %s --check-prefix=CHECK-7-3 +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 17 1 2>&1 | FileCheck %s --check-prefix=CHECK-17-1 +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 15 2 2>&1 | FileCheck %s --check-prefix=CHECK-15-2 +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 18 3 2>&1 | FileCheck %s --check-prefix=CHECK-18-3 +// RUN: rm -f caller-callee*.sancov +// +// REQUIRES: asan-64-bits +// UNSUPPORTED: android +// +// CHECK-10-1: CovDump: 10 caller-callee pairs written +// CHECK-9-2: CovDump: 18 caller-callee pairs written +// CHECK-7-3: CovDump: 21 caller-callee pairs written +// CHECK-17-1: CovDump: 14 caller-callee pairs written +// CHECK-15-2: CovDump: 28 caller-callee pairs written +// CHECK-18-3: CovDump: 42 caller-callee pairs written + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +int P = 0; +struct Foo {virtual void f() {if (P) printf("Foo::f()\n");}}; +struct Foo1 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo2 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo3 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo4 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo5 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo6 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo7 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo8 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo9 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo10 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo11 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo12 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo13 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo14 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo15 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo16 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo17 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo18 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; +struct Foo19 : Foo {virtual void f() {if (P) printf("%d\n", __LINE__);}}; + +Foo *foo[20] = { + new Foo, new Foo1, new Foo2, new Foo3, new Foo4, new Foo5, new Foo6, + new Foo7, new Foo8, new Foo9, new Foo10, new Foo11, new Foo12, new Foo13, + new Foo14, new Foo15, new Foo16, new Foo17, new Foo18, new Foo19, +}; + +int n_functions = 10; +int n_callers = 2; + +void *Thread(void *arg) { + if (n_callers >= 1) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f(); + if (n_callers >= 2) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f(); + if (n_callers >= 3) for (int i = 0; i < 2000; i++) foo[i % n_functions]->f(); + return arg; +} + +int main(int argc, char **argv) { + if (argc >= 2) + n_functions = atoi(argv[1]); + if (argc >= 3) + n_callers = atoi(argv[2]); + const int kNumThreads = 16; + pthread_t t[kNumThreads]; + for (int i = 0; i < kNumThreads; i++) + pthread_create(&t[i], 0, Thread, 0); + for (int i = 0; i < kNumThreads; i++) + pthread_join(t[i], 0); +} diff --git a/test/asan/TestCases/Posix/coverage-direct-activation.cc b/test/asan/TestCases/Posix/coverage-direct-activation.cc index af73f5d2952d..0af3296f22d4 100644 --- a/test/asan/TestCases/Posix/coverage-direct-activation.cc +++ b/test/asan/TestCases/Posix/coverage-direct-activation.cc @@ -7,11 +7,11 @@ // RUN: rm -rf %T/coverage-direct-activation // RUN: mkdir -p %T/coverage-direct-activation/normal -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1,coverage_direct=0,coverage_dir=%T/coverage-direct-activation/normal:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1,coverage_direct=0,coverage_dir=%T/coverage-direct-activation/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct-activation/normal/*.sancov >%T/coverage-direct-activation/normal/out.txt // RUN: mkdir -p %T/coverage-direct-activation/direct -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,coverage_direct=1,verbosity=1 \ +// RUN: %env_asan_opts=start_deactivated=1,coverage_direct=1,verbosity=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=coverage=1,coverage_dir=%T/coverage-direct-activation/direct %run %t %dynamiclib // RUN: cd %T/coverage-direct-activation/direct // RUN: %sancov rawunpack *.sancov.raw @@ -23,7 +23,7 @@ // RUN: diff -u coverage-direct-activation/normal/out.txt coverage-direct-activation/direct/out.txt // RUN: mkdir -p %T/coverage-direct-activation/direct2 -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,coverage=1,coverage_direct=1,verbosity=1 \ +// RUN: %env_asan_opts=start_deactivated=1,coverage=1,coverage_direct=1,verbosity=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=coverage_dir=%T/coverage-direct-activation/direct2 %run %t %dynamiclib // RUN: cd %T/coverage-direct-activation/direct2 // RUN: %sancov rawunpack *.sancov.raw diff --git a/test/asan/TestCases/Posix/coverage-direct-large.cc b/test/asan/TestCases/Posix/coverage-direct-large.cc index 2769172c39ab..367a5667a711 100644 --- a/test/asan/TestCases/Posix/coverage-direct-large.cc +++ b/test/asan/TestCases/Posix/coverage-direct-large.cc @@ -8,12 +8,12 @@ // RUN: rm -rf %T/coverage-direct-large // RUN: mkdir -p %T/coverage-direct-large/normal && cd %T/coverage-direct-large/normal -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=0:verbosity=1 %run %t %dynamiclib // RUN: %sancov print *.sancov >out.txt // RUN: cd ../.. // RUN: mkdir -p %T/coverage-direct-large/direct && cd %T/coverage-direct-large/direct -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=1:verbosity=1 %run %t %dynamiclib // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt // RUN: cd ../.. diff --git a/test/asan/TestCases/Posix/coverage-direct.cc b/test/asan/TestCases/Posix/coverage-direct.cc index 5371a859c24f..8caa9c553f2e 100644 --- a/test/asan/TestCases/Posix/coverage-direct.cc +++ b/test/asan/TestCases/Posix/coverage-direct.cc @@ -6,11 +6,11 @@ // RUN: rm -rf %T/coverage-direct // RUN: mkdir -p %T/coverage-direct/normal -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt // RUN: mkdir -p %T/coverage-direct/direct -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib // RUN: cd %T/coverage-direct/direct // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt @@ -25,11 +25,11 @@ // RUN: rm -rf %T/coverage-direct // RUN: mkdir -p %T/coverage-direct/normal -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt // RUN: mkdir -p %T/coverage-direct/direct -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib // RUN: cd %T/coverage-direct/direct // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt @@ -44,11 +44,11 @@ // RUN: rm -rf %T/coverage-direct // RUN: mkdir -p %T/coverage-direct/normal -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt // RUN: mkdir -p %T/coverage-direct/direct -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib +// RUN: %env_asan_opts=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib // RUN: cd %T/coverage-direct/direct // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt diff --git a/test/asan/TestCases/Posix/coverage-fork-direct.cc b/test/asan/TestCases/Posix/coverage-fork-direct.cc index 39363911fec3..c19671953809 100644 --- a/test/asan/TestCases/Posix/coverage-fork-direct.cc +++ b/test/asan/TestCases/Posix/coverage-fork-direct.cc @@ -1,7 +1,7 @@ // RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t // RUN: rm -rf %T/coverage-fork-direct // RUN: mkdir -p %T/coverage-fork-direct && cd %T/coverage-fork-direct -// RUN: (ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:verbosity=1 %run %t; \ +// RUN: (%env_asan_opts=coverage=1:coverage_direct=1:verbosity=1 %run %t; \ // RUN: %sancov rawunpack *.sancov.raw; %sancov print *.sancov) 2>&1 // // XFAIL: android diff --git a/test/asan/TestCases/Posix/coverage-fork.cc b/test/asan/TestCases/Posix/coverage-fork.cc index c1f0fc3a84b8..799d71638a26 100644 --- a/test/asan/TestCases/Posix/coverage-fork.cc +++ b/test/asan/TestCases/Posix/coverage-fork.cc @@ -1,8 +1,7 @@ // RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t -// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:verbosity=1 // RUN: rm -rf %T/coverage-fork // RUN: mkdir -p %T/coverage-fork && cd %T/coverage-fork -// RUN: %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=coverage=1:coverage_direct=0:verbosity=1 %run %t 2>&1 | FileCheck %s // // XFAIL: android diff --git a/test/asan/TestCases/Posix/coverage-maybe-open-file.cc b/test/asan/TestCases/Posix/coverage-maybe-open-file.cc new file mode 100644 index 000000000000..cab3d5770aa5 --- /dev/null +++ b/test/asan/TestCases/Posix/coverage-maybe-open-file.cc @@ -0,0 +1,32 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// XFAIL: android +// +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t +// RUN: rm -rf %T/coverage-maybe-open-file +// RUN: mkdir -p %T/coverage-maybe-open-file && cd %T/coverage-maybe-open-file +// RUN: %env_asan_opts=coverage=1 %run %t | FileCheck %s --check-prefix=CHECK-success +// RUN: %env_asan_opts=coverage=0 %run %t | FileCheck %s --check-prefix=CHECK-fail +// RUN: [ "$(cat test.sancov.packed)" == "test" ] +// RUN: cd .. && rm -rf %T/coverage-maybe-open-file + +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <sanitizer/coverage_interface.h> + +// FIXME: the code below might not work on Windows. +int main(int argc, char **argv) { + int fd = __sanitizer_maybe_open_cov_file("test"); + if (fd > 0) { + printf("SUCCESS\n"); + const char s[] = "test\n"; + write(fd, s, strlen(s)); + close(fd); + } else { + printf("FAIL\n"); + } +} + +// CHECK-success: SUCCESS +// CHECK-fail: FAIL diff --git a/test/asan/TestCases/Posix/coverage-module-unloaded.cc b/test/asan/TestCases/Posix/coverage-module-unloaded.cc index fe08bdd792b1..d492af6662fa 100644 --- a/test/asan/TestCases/Posix/coverage-module-unloaded.cc +++ b/test/asan/TestCases/Posix/coverage-module-unloaded.cc @@ -3,10 +3,9 @@ // RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib1 -fPIC // RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib2 -fPIC // RUN: %clangxx_asan -fsanitize-coverage=func %s %libdl -o %t -// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 // RUN: mkdir -p %T/coverage-module-unloaded && cd %T/coverage-module-unloaded -// RUN: %run %t %dynamiclib1 %dynamiclib2 2>&1 | FileCheck %s -// RUN: %run %t %dynamiclib1 %dynamiclib2 foo 2>&1 | FileCheck %s +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t %dynamiclib1 %dynamiclib2 2>&1 | FileCheck %s +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t %dynamiclib1 %dynamiclib2 foo 2>&1 | FileCheck %s // RUN: rm -r %T/coverage-module-unloaded // // https://code.google.com/p/address-sanitizer/issues/detail?id=263 diff --git a/test/asan/TestCases/Posix/coverage-sandboxing.cc b/test/asan/TestCases/Posix/coverage-sandboxing.cc index dd2c1ec43be5..f6fc5266607c 100644 --- a/test/asan/TestCases/Posix/coverage-sandboxing.cc +++ b/test/asan/TestCases/Posix/coverage-sandboxing.cc @@ -1,16 +1,16 @@ // RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so // RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t %ld_flags_rpath_exe -// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 + // RUN: rm -rf %T/coverage_sandboxing_test // RUN: mkdir %T/coverage_sandboxing_test && cd %T/coverage_sandboxing_test // RUN: mkdir vanilla && cd vanilla -// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-vanilla +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-vanilla // RUN: mkdir ../sandbox1 && cd ../sandbox1 -// RUN: %run %t a 2>&1 | FileCheck %s --check-prefix=CHECK-sandbox -// RUN: %sancov unpack coverage_sandboxing_test.sancov.packed +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t a 2>&1 | FileCheck %s --check-prefix=CHECK-sandbox +// RUN: %sancov unpack coverage_sandboxing_test.sancov.packed // RUN: mkdir ../sandbox2 && cd ../sandbox2 -// RUN: %run %t a b 2>&1 | FileCheck %s --check-prefix=CHECK-sandbox -// RUN: %sancov unpack coverage_sandboxing_test.sancov.packed +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t a b 2>&1 | FileCheck %s --check-prefix=CHECK-sandbox +// RUN: %sancov unpack coverage_sandboxing_test.sancov.packed // RUN: cd .. // RUN: %sancov print vanilla/`basename %dynamiclib`*.sancov > vanilla.txt // RUN: %sancov print sandbox1/`basename %dynamiclib`*.sancov > sandbox1.txt @@ -18,6 +18,7 @@ // RUN: diff vanilla.txt sandbox1.txt // RUN: diff vanilla.txt sandbox2.txt // RUN: rm -r %T/coverage_sandboxing_test + // https://code.google.com/p/address-sanitizer/issues/detail?id=263 // XFAIL: android diff --git a/test/asan/TestCases/Posix/coverage.cc b/test/asan/TestCases/Posix/coverage.cc index 99e348fdaf9d..7c1c4949f60c 100644 --- a/test/asan/TestCases/Posix/coverage.cc +++ b/test/asan/TestCases/Posix/coverage.cc @@ -1,20 +1,19 @@ // RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so // RUN: %clangxx_asan -fsanitize-coverage=func %s %ld_flags_rpath_exe -o %t -// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 // RUN: rm -rf %T/coverage && mkdir -p %T/coverage && cd %T/coverage -// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-main +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-main // RUN: %sancov print `ls coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1 -// RUN: %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-foo +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-foo // RUN: %sancov print `ls coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 -// RUN: %run %t bar 2>&1 | FileCheck %s --check-prefix=CHECK-bar +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t bar 2>&1 | FileCheck %s --check-prefix=CHECK-bar // RUN: %sancov print `ls *coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 -// RUN: %run %t foo bar 2>&1 | FileCheck %s --check-prefix=CHECK-foo-bar +// RUN: %env_asan_opts=coverage=1:verbosity=1 %run %t foo bar 2>&1 | FileCheck %s --check-prefix=CHECK-foo-bar // RUN: %sancov print `ls *coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 // RUN: %sancov print `ls *coverage.*sancov | grep '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1 // RUN: %sancov merge `ls *coverage.*sancov | grep -v '.so'` > merged-cov // RUN: %sancov print merged-cov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 -// RUN: not %run %t foo bar 4 2>&1 | FileCheck %s --check-prefix=CHECK-report -// RUN: not %run %t foo bar 4 5 2>&1 | FileCheck %s --check-prefix=CHECK-segv +// RUN: %env_asan_opts=coverage=1:verbosity=1 not %run %t foo bar 4 2>&1 | FileCheck %s --check-prefix=CHECK-report +// RUN: %env_asan_opts=coverage=1:verbosity=1 not %run %t foo bar 4 5 2>&1 | FileCheck %s --check-prefix=CHECK-segv // RUN: rm -r %T/coverage // // https://code.google.com/p/address-sanitizer/issues/detail?id=263 diff --git a/test/asan/TestCases/Posix/current_allocated_bytes.cc b/test/asan/TestCases/Posix/current_allocated_bytes.cc new file mode 100644 index 000000000000..c49e433b1e8b --- /dev/null +++ b/test/asan/TestCases/Posix/current_allocated_bytes.cc @@ -0,0 +1,44 @@ +// RUN: %clangxx_asan -O0 %s -pthread -o %t && %run %t +// RUN: %clangxx_asan -O2 %s -pthread -o %t && %run %t +// REQUIRES: stable-runtime + +#include <assert.h> +#include <pthread.h> +#include <sanitizer/allocator_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(__sanitizer_get_current_allocated_bytes() > 0); + return 0; +} + +int main() { + size_t used_mem = __sanitizer_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 = __sanitizer_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/test/asan/TestCases/Posix/deep_call_stack.cc b/test/asan/TestCases/Posix/deep_call_stack.cc new file mode 100644 index 000000000000..18ba563dbd21 --- /dev/null +++ b/test/asan/TestCases/Posix/deep_call_stack.cc @@ -0,0 +1,25 @@ +// Check that UAR mode can handle very deep recusrion. +// RUN: %clangxx_asan -O2 %s -o %t && \ +// RUN: (ulimit -s 4096; %env_asan_opts=detect_stack_use_after_return=1 %run %t) 2>&1 | FileCheck %s + +// Also check that use_sigaltstack+verbosity doesn't crash. +// RUN: %env_asan_opts=verbosity=1:use_sigaltstack=1:detect_stack_use_after_return=1 %run %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(15000, 0); + return 0; +} +// CHECK: [15000] ptr: +// CHECK: [07000] ptr: +// CHECK: [00000] ptr: diff --git a/test/asan/TestCases/Posix/deep_thread_stack.cc b/test/asan/TestCases/Posix/deep_thread_stack.cc new file mode 100644 index 000000000000..535da79ff58d --- /dev/null +++ b/test/asan/TestCases/Posix/deep_thread_stack.cc @@ -0,0 +1,58 @@ +// RUN: %clangxx_asan -O0 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s +// REQUIRES: stable-runtime + +#include <pthread.h> + +int *x; + +void *AllocThread(void *arg) { + x = new int; + *x = 42; + return NULL; +} + +void *FreeThread(void *arg) { + delete x; + return NULL; +} + +void *AccessThread(void *arg) { + *x = 43; // BOOM + return NULL; +} + +typedef void* (*callback_type)(void* arg); + +void *RunnerThread(void *function) { + pthread_t thread; + pthread_create(&thread, NULL, (callback_type)function, NULL); + pthread_join(thread, NULL); + return NULL; +} + +void RunThread(callback_type function) { + pthread_t runner; + pthread_create(&runner, NULL, RunnerThread, (void*)function); + pthread_join(runner, NULL); +} + +int main(int argc, char *argv[]) { + RunThread(AllocThread); + RunThread(FreeThread); + RunThread(AccessThread); + return (x != 0); +} + +// CHECK: AddressSanitizer: heap-use-after-free +// CHECK: WRITE of size 4 at 0x{{.*}} thread T[[ACCESS_THREAD:[0-9]+]] +// CHECK: freed by thread T[[FREE_THREAD:[0-9]+]] here: +// CHECK: previously allocated by thread T[[ALLOC_THREAD:[0-9]+]] here: +// CHECK: Thread T[[ACCESS_THREAD]] created by T[[ACCESS_RUNNER:[0-9]+]] here: +// CHECK: Thread T[[ACCESS_RUNNER]] created by T0 here: +// CHECK: Thread T[[FREE_THREAD]] created by T[[FREE_RUNNER:[0-9]+]] here: +// CHECK: Thread T[[FREE_RUNNER]] created by T0 here: +// CHECK: Thread T[[ALLOC_THREAD]] created by T[[ALLOC_RUNNER:[0-9]+]] here: +// CHECK: Thread T[[ALLOC_RUNNER]] created by T0 here: diff --git a/test/asan/TestCases/Posix/dlclose-test.cc b/test/asan/TestCases/Posix/dlclose-test.cc new file mode 100644 index 000000000000..369abd3127cc --- /dev/null +++ b/test/asan/TestCases/Posix/dlclose-test.cc @@ -0,0 +1,106 @@ +// Regression test for +// http://code.google.com/p/address-sanitizer/issues/detail?id=19 +// Bug description: +// 1. application dlopens foo.so +// 2. asan registers all globals from foo.so +// 3. application dlcloses foo.so +// 4. application mmaps some memory to the location where foo.so was before +// 5. application starts using this mmaped memory, but asan still thinks there +// are globals. +// 6. BOOM + +// This sublte test assumes that after a foo.so is dlclose-d +// we can mmap the region of memory that has been occupied by the library. +// It works on i368/x86_64 Linux, but not necessary anywhere else. +// REQUIRES: x86_64-supported-target,i386-supported-target + +// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O0 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 -DSHARED_LIB %s -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O1 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 -DSHARED_LIB %s -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O2 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 -DSHARED_LIB %s -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O3 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s + +#if !defined(SHARED_LIB) +#include <assert.h> +#include <dlfcn.h> +#include <stdio.h> +#include <string.h> +#include <sys/mman.h> +#include <unistd.h> + +#include <string> + +#if defined(__FreeBSD__) +// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before +// that, it was never implemented. So just define it to zero. +#undef MAP_NORESERVE +#define MAP_NORESERVE 0 +#endif + +using std::string; + +typedef int *(fun_t)(); + +int main(int argc, char *argv[]) { + string path = string(argv[0]) + "-so.so"; + size_t PageSize = sysconf(_SC_PAGESIZE); + 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 *get = (fun_t*)dlsym(lib, "get_address_of_static_var"); + if (!get) { + printf("failed dlsym\n"); + return 1; + } + int *addr = get(); + assert(((size_t)addr % 32) == 0); // should be 32-byte aligned. + printf("addr: %p\n", addr); + addr[0] = 1; // make sure we can write there. + + // Now dlclose the shared library. + printf("attempting to dlclose\n"); + if (dlclose(lib)) { + printf("failed to dlclose\n"); + return 1; + } + // Now, the page where 'addr' is unmapped. Map it. + size_t page_beg = ((size_t)addr) & ~(PageSize - 1); + void *res = mmap((void*)(page_beg), PageSize, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_NORESERVE, -1, 0); + if (res == (char*)-1L) { + printf("failed to mmap\n"); + return 1; + } + addr[1] = 2; // BOOM (if the bug is not fixed). + printf("PASS\n"); + // CHECK: PASS + return 0; +} +#else // SHARED_LIB +#include <stdio.h> + +static int pad1; +static int static_var; +static int pad2; + +extern "C" +int *get_address_of_static_var() { + return &static_var; +} + +__attribute__((constructor)) +void at_dlopen() { + printf("%s: I am being dlopened\n", __FILE__); +} +__attribute__((destructor)) +void at_dlclose() { + printf("%s: I am being dlclosed\n", __FILE__); +} +#endif // SHARED_LIB diff --git a/test/asan/TestCases/Posix/free_hook_realloc.cc b/test/asan/TestCases/Posix/free_hook_realloc.cc new file mode 100644 index 000000000000..cbc5d6fed56e --- /dev/null +++ b/test/asan/TestCases/Posix/free_hook_realloc.cc @@ -0,0 +1,34 @@ +// Check that free hook doesn't conflict with Realloc. +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s + +#include <stdlib.h> +#include <unistd.h> +#include <sanitizer/allocator_interface.h> + +static void *glob_ptr; + +extern "C" { +void __sanitizer_free_hook(const volatile 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/test/asan/TestCases/Posix/freopen.cc b/test/asan/TestCases/Posix/freopen.cc new file mode 100644 index 000000000000..c137abb8fcb8 --- /dev/null +++ b/test/asan/TestCases/Posix/freopen.cc @@ -0,0 +1,15 @@ +// RUN: %clangxx_asan -O0 %s -o %t && %run %t + +// This fails on i386 Linux due to a glibc versioned symbols mixup. +// REQUIRES: asan-64-bits + +#include <assert.h> +#include <stdio.h> + +int main() { + FILE *fp = fopen("/dev/null", "w"); + assert(fp); + freopen(NULL, "a", fp); + fclose(fp); + return 0; +} diff --git a/test/asan/TestCases/Posix/gc-test.cc b/test/asan/TestCases/Posix/gc-test.cc new file mode 100644 index 000000000000..56d8c398fc75 --- /dev/null +++ b/test/asan/TestCases/Posix/gc-test.cc @@ -0,0 +1,54 @@ +// RUN: %clangxx_asan %s -pthread -o %t +// RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: %clangxx_asan -O3 %s -pthread -o %t +// RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 +// REQUIRES: stable-runtime + +#include <assert.h> +#include <stdio.h> +#include <pthread.h> +#include <sanitizer/asan_interface.h> + +static const int kNumThreads = 2; +static const int kLeftRedzoneSize = sizeof(void *) * 4; + +void *Thread(void *unused) { + void *fake_stack = __asan_get_current_fake_stack(); + char var[15]; + if (fake_stack) { + fprintf(stderr, "fake stack found: %p; var: %p\n", fake_stack, var); + // CHECK1: fake stack found + // CHECK1: fake stack found + void *beg, *end; + void *real_stack = + __asan_addr_is_in_fake_stack(fake_stack, &var[0], &beg, &end); + assert(real_stack); + assert((char*)beg <= (char*)&var[0]); + assert((char*)end > (char*)&var[0]); + for (int i = -kLeftRedzoneSize; i < 15; i++) { + void *beg1, *end1; + char *ptr = &var[0] + i; + void *real_stack1 = + __asan_addr_is_in_fake_stack(fake_stack, ptr, &beg1, &end1); + assert(real_stack == real_stack1); + assert(beg == beg1); + assert(end == end1); + } + } else { + fprintf(stderr, "no fake stack\n"); + // CHECK0: no fake stack + // CHECK0: no fake stack + } + return NULL; +} + +int main(int argc, char **argv) { + pthread_t t[kNumThreads]; + for (int i = 0; i < kNumThreads; i++) + pthread_create(&t[i], 0, Thread, 0); + for (int i = 0; i < kNumThreads; i++) + pthread_join(t[i], 0); + return 0; +} diff --git a/test/asan/TestCases/Posix/halt_on_error-signals.c b/test/asan/TestCases/Posix/halt_on_error-signals.c new file mode 100644 index 000000000000..60916f6570fc --- /dev/null +++ b/test/asan/TestCases/Posix/halt_on_error-signals.c @@ -0,0 +1,102 @@ +// Test interaction of Asan recovery mode with asynch signals. +// +// RUN: %clang_asan -fsanitize-recover=address -pthread %s -o %t +// +// RUN: rm -f %t.log +// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 100 >%t.log 2>&1 || true +// Collision will almost always get triggered but we still need to check the unlikely case: +// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < %t.log || FileCheck --check-prefix=CHECK-NO-COLLISION %s < %t.log + +#define _SVID_SOURCE 1 // SA_NODEFER + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include <time.h> +#include <signal.h> + +#include <sanitizer/asan_interface.h> + +void random_delay(unsigned *seed) { + *seed = 1664525 * *seed + 1013904223; + struct timespec delay = { 0, (*seed % 1000) * 1000 }; + nanosleep(&delay, 0); +} + +volatile char bad[2] = {1, }; + +void error() { + // CHECK-COLLISION: AddressSanitizer: nested bug in the same thread, aborting + // CHECK-NO-COLLISION: AddressSanitizer: use-after-poison + volatile int idx = 0; + bad[idx] = 0; +} + +#define CHECK_CALL(e, msg) do { \ + if (0 != (e)) { \ + fprintf(stderr, "Failed to " msg "\n"); \ + exit(1); \ + } \ +} while (0) + +size_t niter = 10; +pthread_t sender_tid, receiver_tid; + +pthread_mutex_t keep_alive_mu = PTHREAD_MUTEX_INITIALIZER; + +void *sender(void *arg) { + unsigned seed = 0; + for (size_t i = 0; i < niter; ++i) { + random_delay(&seed); + CHECK_CALL(pthread_kill(receiver_tid, SIGUSR1), "send signal"); + } + return 0; +} + +void handler(int sig) { + // Expect error collisions here + error(); +} + +void *receiver(void *arg) { + unsigned seed = 1; + for (size_t i = 0; i < niter; ++i) { + random_delay(&seed); + // And here + error(); + } + // Parent will release this when it's ok to terminate + CHECK_CALL(pthread_mutex_lock(&keep_alive_mu), "unlock mutex"); + return 0; +} + +int main(int argc, char **argv) { + if (argc != 2) { + fprintf(stderr, "Syntax: %s niter\n", argv[0]); + exit(1); + } + + niter = (size_t)strtoul(argv[1], 0, 0); + + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler; + sa.sa_flags = SA_NODEFER; // Enable nested handlers to add more stress + CHECK_CALL(sigaction(SIGUSR1, &sa, 0), "set sighandler"); + + __asan_poison_memory_region(&bad, sizeof(bad)); + + CHECK_CALL(pthread_mutex_lock(&keep_alive_mu), "lock mutex"); + CHECK_CALL(pthread_create(&receiver_tid, 0, receiver, 0), "start thread"); + CHECK_CALL(pthread_create(&sender_tid, 0, sender, 0), "start thread"); + CHECK_CALL(pthread_join(sender_tid, 0), "join thread"); + // Now allow receiver to die + CHECK_CALL(pthread_mutex_unlock(&keep_alive_mu), "unlock mutex"); + CHECK_CALL(pthread_join(receiver_tid, 0), "join thread"); + + // CHECK-NO-COLLISION: All threads terminated + printf("All threads terminated\n"); + + return 0; +} diff --git a/test/asan/TestCases/Posix/halt_on_error-torture.cc b/test/asan/TestCases/Posix/halt_on_error-torture.cc new file mode 100644 index 000000000000..019f7d126a47 --- /dev/null +++ b/test/asan/TestCases/Posix/halt_on_error-torture.cc @@ -0,0 +1,87 @@ +// Stress test recovery mode with many threads. +// +// RUN: %clangxx_asan -fsanitize-recover=address -pthread %s -o %t +// +// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 1 10 >1.txt 2>&1 +// RUN: FileCheck %s < 1.txt +// RUN: [ $(grep -c 'ERROR: AddressSanitizer: use-after-poison' 1.txt) -eq 10 ] +// RUN: FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt +// +// Collisions are unlikely but still possible so we need the ||. +// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 10 20 >10.txt 2>&1 || true +// This one is racy although _very_ unlikely to fail: +// RUN: FileCheck %s < 10.txt +// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt +// +// Collisions are unlikely but still possible so we need the ||. +// RUN: %env_asan_opts=halt_on_error=false %run %t 10 20 >10.txt 2>&1 || true +// This one is racy although _very_ unlikely to fail: +// RUN: FileCheck %s < 10.txt +// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt + +#include <stdio.h> +#include <stdlib.h> +#include <pthread.h> +#include <time.h> + +#include <sanitizer/asan_interface.h> + +size_t nthreads = 10; +size_t niter = 10; + +void random_delay(unsigned *seed) { + *seed = 1664525 * *seed + 1013904223; + struct timespec delay = { 0, (*seed % 1000) * 1000 }; + nanosleep(&delay, 0); +} + +void *run(void *arg) { + unsigned seed = (unsigned)(size_t)arg; + + volatile char tmp[2]; + __asan_poison_memory_region(&tmp, sizeof(tmp)); + + for (size_t i = 0; i < niter; ++i) { + random_delay(&seed); + // Expect error collisions here + // CHECK: ERROR: AddressSanitizer: use-after-poison + volatile int idx = 0; + tmp[idx] = 0; + } + + return 0; +} + +int main(int argc, char **argv) { + if (argc != 3) { + fprintf(stderr, "Syntax: %s nthreads niter\n", argv[0]); + exit(1); + } + + nthreads = (size_t)strtoul(argv[1], 0, 0); + niter = (size_t)strtoul(argv[2], 0, 0); + + pthread_t *tids = new pthread_t[nthreads]; + + for (size_t i = 0; i < nthreads; ++i) { + if (0 != pthread_create(&tids[i], 0, run, (void *)i)) { + fprintf(stderr, "Failed to create thread\n"); + exit(1); + } + } + + for (size_t i = 0; i < nthreads; ++i) { + if (0 != pthread_join(tids[i], 0)) { + fprintf(stderr, "Failed to join thread\n"); + exit(1); + } + } + + // CHECK-COLLISION: AddressSanitizer: nested bug in the same thread, aborting + // CHECK-NO-COLLISION: All threads terminated + printf("All threads terminated\n"); + + delete [] tids; + + return 0; +} diff --git a/test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc b/test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc new file mode 100644 index 000000000000..98b034812ef6 --- /dev/null +++ b/test/asan/TestCases/Posix/halt_on_error_suppress_equal_pcs.cc @@ -0,0 +1,55 @@ +// Test reports dedupication for recovery mode. +// +// RUN: %clang_asan -fsanitize-recover=address %s -o %t +// +// Check for reports dedupication. +// RUN: %env_asan_opts=halt_on_error=false %run %t 2>&1 | FileCheck %s +// +// Check that we die after reaching different reports number threshold. +// RUN: %env_asan_opts=halt_on_error=false not %run %t 1 > %t1.log 2>&1 +// RUN: [ $(grep -c 'ERROR: AddressSanitizer: stack-buffer-overflow' %t1.log) -eq 25 ] +// +// Check suppress_equal_pcs=true behavior is equal to default one. +// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=true %run %t 2>&1 | FileCheck %s +// +// Check suppress_equal_pcs=false behavior isn't equal to default one. +// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t > %t2.log 2>&1 +// RUN: [ $(grep -c 'ERROR: AddressSanitizer: stack-buffer-overflow' %t2.log) -eq 30 ] + +#define ACCESS_ARRAY_FIVE_ELEMENTS(array, i) \ + array[i] = i; \ + array[i + 1] = i + 1; \ + array[i + 2] = i + 2; \ + array[i + 3] = i + 3; \ + array[i + 4] = i + 4; \ + +volatile int ten = 10; +unsigned kNumIterations = 10; + +int main(int argc, char **argv) { + char a[10]; + char b[10]; + + if (argc == 1) { + for (int i = 0; i < kNumIterations; ++i) { + // CHECK: READ of size 1 + volatile int res = a[ten + i]; + // CHECK: WRITE of size 1 + a[i + ten] = res + 3; + // CHECK: READ of size 1 + res = a[ten + i]; + // CHECK-NOT: ERROR + } + } else { + for (int i = 0; i < kNumIterations; ++i) { + ACCESS_ARRAY_FIVE_ELEMENTS(a, ten); + ACCESS_ARRAY_FIVE_ELEMENTS(a, ten + 5); + ACCESS_ARRAY_FIVE_ELEMENTS(a, ten + 10); + ACCESS_ARRAY_FIVE_ELEMENTS(b, ten); + ACCESS_ARRAY_FIVE_ELEMENTS(b, ten + 5); + ACCESS_ARRAY_FIVE_ELEMENTS(b, ten + 10); + } + } + return 0; +} + diff --git a/test/asan/TestCases/Posix/init-order-pthread-create.cc b/test/asan/TestCases/Posix/init-order-pthread-create.cc new file mode 100644 index 000000000000..19c000fec435 --- /dev/null +++ b/test/asan/TestCases/Posix/init-order-pthread-create.cc @@ -0,0 +1,54 @@ +// Check that init-order checking is properly disabled if pthread_create is +// called. + +// RUN: %clangxx_asan -c -DCONFIG1 %s -o %t1.o +// RUN: %clangxx_asan -c %s -o %t2.o +// RUN: %clangxx_asan -pthread %t1.o %t2.o -o %t +// RUN: %env_asan_opts=strict_init_order=true %run %t + +#ifdef CONFIG1 + +#include <stdio.h> +#include <pthread.h> +#include <unistd.h> + +void *bar(void *input, bool sleep_before_init) { + if (sleep_before_init) + usleep(500000); + return input; +} + +void *glob = bar((void*)0x1234, false); +extern void *glob2; + +void *poll(void *arg) { + void **glob = (void**)arg; + while (true) { + usleep(100000); + printf("glob is now: %p\n", *glob); + } +} + +struct GlobalPollerStarter { + GlobalPollerStarter() { + pthread_t p; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&p, 0, poll, &glob); + pthread_attr_destroy(&attr); + printf("glob poller is started"); + } +} global_poller; + +int main() { + printf("%p %p\n", glob, glob2); + return 0; +} + +#else // CONFIG1 + +void *bar(void *input, bool sleep_before_init); +void *glob2 = bar((void*)0x2345, true); + +#endif diff --git a/test/asan/TestCases/Posix/ioctl.cc b/test/asan/TestCases/Posix/ioctl.cc index d25f6ecbee1f..6cf9fa8e3cd3 100644 --- a/test/asan/TestCases/Posix/ioctl.cc +++ b/test/asan/TestCases/Posix/ioctl.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_asan -O0 -g %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:handle_ioctl=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 -g %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:handle_ioctl=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 -g %s -o %t && %env_asan_opts=handle_ioctl=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 -g %s -o %t && %env_asan_opts=handle_ioctl=1 not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O0 -g %s -o %t && %run %t // RUN: %clangxx_asan -O3 -g %s -o %t && %run %t diff --git a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc index b1c99430c75d..b39fa74a3149 100644 --- a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc +++ b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc @@ -2,7 +2,7 @@ // RUN: %clangxx_asan %s -o %t // The memory is released only when the deallocated chunk leaves the quarantine, // otherwise the mmap(p, ...) call overwrites the malloc header. -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=0 %run %t +// RUN: %env_asan_opts=quarantine_size_mb=0 %run %t #include <assert.h> #include <string.h> diff --git a/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled b/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled index 9f09b78f41c7..029bdd1e3372 100644 --- a/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled +++ b/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled @@ -1,7 +1,7 @@ // RUN: %clangxx_asan %s -o %t // RUN: rm -f %t.log.* // Set verbosity to 1 so that the log files are opened prior to fork(). -// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:log_path=%t.log verbosity=1" not %run %t 2> %t.out +// RUN: %env_asan_opts=log_path='"%t.log"':verbosity=1 not %run %t 2> %t.out // RUN: for f in %t.log.* ; do FileCheck %s < $f; done // RUN: [ `ls %t.log.* | wc -l` == 2 ] diff --git a/test/asan/TestCases/Posix/new_array_cookie_test.cc b/test/asan/TestCases/Posix/new_array_cookie_test.cc index bc681857ae67..dd50bf7fe6a8 100644 --- a/test/asan/TestCases/Posix/new_array_cookie_test.cc +++ b/test/asan/TestCases/Posix/new_array_cookie_test.cc @@ -1,8 +1,8 @@ // REQUIRES: asan-64-bits // RUN: %clangxx_asan -O3 %s -o %t // RUN: not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE +// RUN: %env_asan_opts=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE #include <stdio.h> #include <stdlib.h> struct C { diff --git a/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc b/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc index 5998d06756d7..f36da2b5438d 100644 --- a/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc +++ b/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc @@ -1,7 +1,7 @@ // REQUIRES: asan-64-bits // RUN: %clangxx_asan -O3 %s -o %t -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s --check-prefix=COOKIE -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE +// RUN: %env_asan_opts=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s --check-prefix=COOKIE +// RUN: %env_asan_opts=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE #include <stdio.h> #include <stdlib.h> #include <assert.h> diff --git a/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc b/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc index 1cea6f68adb2..0683e391cf23 100644 --- a/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc +++ b/test/asan/TestCases/Posix/new_array_cookie_with_new_from_class.cc @@ -2,8 +2,7 @@ // inside the class. // RUN: %clangxx_asan %s -o %t && %run %t // -// XFAIL: android -// XFAIL: armv7l-unknown-linux-gnueabihf +// XFAIL: arm #include <new> #include <stdlib.h> #include <stdint.h> diff --git a/test/asan/TestCases/Posix/stack-overflow.cc b/test/asan/TestCases/Posix/stack-overflow.cc new file mode 100644 index 000000000000..8ef161862499 --- /dev/null +++ b/test/asan/TestCases/Posix/stack-overflow.cc @@ -0,0 +1,114 @@ +// Test ASan detection of stack-overflow condition. + +// RUN: %clangxx_asan -O0 %s -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -O0 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DTHREAD -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DTHREAD -pthread -o %t && %env_asan_opts=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: not %run %t 2>&1 | FileCheck %s +// REQUIRES: stable-runtime + +#include <assert.h> +#include <stdlib.h> +#include <pthread.h> +#include <unistd.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sanitizer/asan_interface.h> + +const int BS = 1024; +volatile char x; +volatile int y = 1; +volatile int z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13; + +void recursive_func(char *p) { +#if defined(SMALL_FRAME) + char *buf = 0; +#elif defined(SAVE_ALL_THE_REGISTERS) + char *buf = 0; + int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13; + t0 = z0; + t1 = z1; + t2 = z2; + t3 = z3; + t4 = z4; + t5 = z5; + t6 = z6; + t7 = z7; + t8 = z8; + t9 = z9; + t10 = z10; + t11 = z11; + t12 = z12; + t13 = z13; + + z0 = t0; + z1 = t1; + z2 = t2; + z3 = t3; + z4 = t4; + z5 = t5; + z6 = t6; + z7 = t7; + z8 = t8; + z9 = t9; + z10 = t10; + z11 = t11; + z12 = t12; + z13 = t13; +#else + char buf[BS]; + // Check that the stack grows in the righ direction, unless we use fake stack. + if (p && !__asan_get_current_fake_stack()) + assert(p - buf >= BS); + buf[rand() % BS] = 1; + buf[rand() % BS] = 2; + x = buf[rand() % BS]; +#endif + if (y) + recursive_func(buf); + x = 1; // prevent tail call optimization + // CHECK: {{stack-overflow on address 0x.* \(pc 0x.* bp 0x.* sp 0x.* T.*\)}} + // If stack overflow happens during function prologue, stack trace may be + // corrupted. Unwind tables are not always 100% exact there. + // For this reason, we don't do any further checks. +} + +void *ThreadFn(void* unused) { + recursive_func(0); + return 0; +} + +void LimitStackAndReexec(int argc, char **argv) { + struct rlimit rlim; + int res = getrlimit(RLIMIT_STACK, &rlim); + assert(res == 0); + if (rlim.rlim_cur == RLIM_INFINITY) { + rlim.rlim_cur = 256 * 1024; + res = setrlimit(RLIMIT_STACK, &rlim); + assert(res == 0); + + execv(argv[0], argv); + assert(0 && "unreachable"); + } +} + +int main(int argc, char **argv) { + LimitStackAndReexec(argc, argv); +#ifdef THREAD + pthread_t t; + pthread_create(&t, 0, ThreadFn, 0); + pthread_join(t, 0); +#else + recursive_func(0); +#endif + return 0; +} diff --git a/test/asan/TestCases/Posix/stack-use-after-return.cc b/test/asan/TestCases/Posix/stack-use-after-return.cc new file mode 100644 index 000000000000..cf114be97d51 --- /dev/null +++ b/test/asan/TestCases/Posix/stack-use-after-return.cc @@ -0,0 +1,79 @@ +// RUN: %clangxx_asan -O0 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O1 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s +// RUN: %env_asan_opts=detect_stack_use_after_return=0 %run %t +// Regression test for a CHECK failure with small stack size and large frame. +// RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=65536 && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s +// +// Test that we can find UAR in a thread other than main: +// RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t && %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s +// +// Test the max_uar_stack_size_log/min_uar_stack_size_log flag. +// +// RUN: %env_asan_opts=detect_stack_use_after_return=1:max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s +// RUN: %env_asan_opts=detect_stack_use_after_return=1:min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %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 + +#ifndef kStackSize +# define kStackSize 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 {{16|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 {{16|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_attr_t attr; + pthread_attr_init(&attr); + if (kStackSize > 0) + pthread_attr_setstacksize(&attr, kStackSize); + pthread_t t; + pthread_create(&t, &attr, Thread, 0); + pthread_attr_destroy(&attr); + pthread_join(t, 0); +#else + Func2(Func1()); +#endif + return 0; +} diff --git a/test/asan/TestCases/Posix/start-deactivated.cc b/test/asan/TestCases/Posix/start-deactivated.cc index 2ca8015fc742..b30141549014 100644 --- a/test/asan/TestCases/Posix/start-deactivated.cc +++ b/test/asan/TestCases/Posix/start-deactivated.cc @@ -5,17 +5,17 @@ // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so // RUN: %clangxx -O0 %s -c -o %t.o // RUN: %clangxx_asan -O0 %t.o %libdl -o %t -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,allocator_may_return_null=0 \ +// RUN: %env_asan_opts=start_deactivated=1,allocator_may_return_null=0 \ // RUN: ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \ +// RUN: %env_asan_opts=start_deactivated=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HELP -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,verbosity=1 \ +// RUN: %env_asan_opts=start_deactivated=1,verbosity=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \ +// RUN: %env_asan_opts=start_deactivated=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED-V0 // Check that verbosity=1 in activation flags affects reporting of unrecognized activation flags. -// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \ +// RUN: %env_asan_opts=start_deactivated=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0,verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED // XFAIL: arm-linux-gnueabi diff --git a/test/asan/TestCases/Posix/tsd_dtor_leak.cc b/test/asan/TestCases/Posix/tsd_dtor_leak.cc index 69d28194fb9e..9e71ff61cf02 100644 --- a/test/asan/TestCases/Posix/tsd_dtor_leak.cc +++ b/test/asan/TestCases/Posix/tsd_dtor_leak.cc @@ -1,7 +1,7 @@ // 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: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=0 %run %t +// RUN: %env_asan_opts=quarantine_size_mb=0 %run %t #include <pthread.h> #include <stdio.h> #include <stdlib.h> diff --git a/test/asan/TestCases/Posix/wait.cc b/test/asan/TestCases/Posix/wait.cc index 99d0212acfab..ed6f326b57d6 100644 --- a/test/asan/TestCases/Posix/wait.cc +++ b/test/asan/TestCases/Posix/wait.cc @@ -4,12 +4,6 @@ // RUN: %clangxx_asan -DWAITPID -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -DWAITPID -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -DWAIT3 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -DWAIT3 -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s - -// RUN: %clangxx_asan -DWAIT3_RUSAGE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -DWAIT3_RUSAGE -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s - #include <assert.h> #include <sys/wait.h> @@ -25,12 +19,6 @@ int main(int argc, char **argv) { res = wait(status); #elif defined(WAITPID) res = waitpid(pid, status, WNOHANG); -#elif defined(WAIT3) - res = wait3(status, WNOHANG, NULL); -#elif defined(WAIT3_RUSAGE) - struct rusage *ru = (struct rusage*)(x + argc * 3); - int good_status; - res = wait3(&good_status, WNOHANG, ru); #endif // CHECK: stack-buffer-overflow // CHECK: {{WRITE of size .* at 0x.* thread T0}} diff --git a/test/asan/TestCases/Posix/wait3.cc b/test/asan/TestCases/Posix/wait3.cc new file mode 100644 index 000000000000..2da816fed1aa --- /dev/null +++ b/test/asan/TestCases/Posix/wait3.cc @@ -0,0 +1,36 @@ +// RUN: %clangxx_asan -DWAIT3 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAIT3 -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s + +// RUN: %clangxx_asan -DWAIT3_RUSAGE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -DWAIT3_RUSAGE -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s + +// UNSUPPORTED: android + +#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(WAIT3) + res = wait3(status, WNOHANG, NULL); +#elif defined(WAIT3_RUSAGE) + struct rusage *ru = (struct rusage*)(x + argc * 3); + int good_status; + res = wait3(&good_status, WNOHANG, ru); +#endif + // CHECK: stack-buffer-overflow + // CHECK: {{WRITE of size .* at 0x.* thread T0}} + // CHECK: {{in .*wait}} + // CHECK: {{in main .*wait3.cc:}} + // CHECK: is located in stack of thread T0 at offset + // CHECK: {{in main}} + return res == -1 ? 1 : 0; + } + // child + return 0; +} |