diff options
author | Alex Shlyapnikov <alekseys@google.com> | 2017-12-04 18:00:24 +0000 |
---|---|---|
committer | Alex Shlyapnikov <alekseys@google.com> | 2017-12-04 18:00:24 +0000 |
commit | 1ce8e22e8474d244b05bb842ef54e9d5af7188bc (patch) | |
tree | cabc1a5ab34ed91fd5f334b48a5ec4add8aad7b0 /test | |
parent | 5551897294887d632c71275cf11c5654fd80cda7 (diff) |
[ASan] Enhance libsanitizer support for invalid-pointer-pair.
Following patch adds support of all memory origins in
CheckForInvalidPointerPair function. For small difference of pointers,
it's directly done in shadow memory (the limit was set to 2048B).
Then we search for origin of first pointer and verify that the second
one has the same origin. If so, we verify that it points either to a same
variable (in case of stack memory or a global variable), or to a same
heap segment.
Committing on behanf of marxin and jakubjelinek.
Reviewers: alekseyshl, kcc
Subscribers: llvm-commits
Differential revision: https://reviews.llvm.org/D40600
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319668 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
5 files changed, 312 insertions, 0 deletions
diff --git a/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc b/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc new file mode 100644 index 000000000..db7f2b7fb --- /dev/null +++ b/test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc @@ -0,0 +1,54 @@ +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair + +// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t a 2>&1 | FileCheck %s -check-prefix=OK -allow-empty +// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t b 2>&1 | FileCheck %s -check-prefix=B + +#include <assert.h> +#include <pthread.h> +#include <stdlib.h> +#include <unistd.h> + +char *pointers[2]; +pthread_barrier_t bar; + +void *thread_main(void *n) { + char local; + + unsigned long id = (unsigned long)n; + pointers[id] = &local; + pthread_barrier_wait(&bar); + pthread_barrier_wait(&bar); + + return NULL; +} + +int main(int argc, char **argv) { + assert(argc >= 2); + + char t = argv[1][0]; + + pthread_t threads[2]; + pthread_barrier_init(&bar, NULL, 3); + pthread_create(&threads[0], 0, thread_main, (void *)0); + pthread_create(&threads[1], 0, thread_main, (void *)1); + pthread_barrier_wait(&bar); + + if (t == 'a') { + // OK-NOT: not handled yet + unsigned r = pointers[0] - pointers[1]; + } else { + char local; + char *parent_pointer = &local; + + // B: ERROR: AddressSanitizer: invalid-pointer-pair + // B: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-threads.cc:[[@LINE+1]] + unsigned r = parent_pointer - pointers[0]; + } + + pthread_barrier_wait(&bar); + pthread_join(threads[0], 0); + pthread_join(threads[1], 0); + pthread_barrier_destroy(&bar); + + return 0; +} diff --git a/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc b/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc new file mode 100644 index 000000000..82f63359e --- /dev/null +++ b/test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc @@ -0,0 +1,103 @@ +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair + +// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1:halt_on_error=0 %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> + +int foo(char *p, char *q) { + return p > q; +} + +char global1[100] = {}, global2[100] = {}; +char small_global[7] = {}; +char large_global[5000] = {}; + +int main() { + // Heap allocated memory. + char *heap1 = (char *)malloc(42); + char *heap2 = (char *)malloc(42); + + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(heap1, heap2); + free(heap1); + free(heap2); + + heap1 = (char *)malloc(1024); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(heap1, heap1 + 1025); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(heap1 + 1024, heap1 + 1025); + free(heap1); + + heap1 = (char *)malloc(4096); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(heap1, heap1 + 4097); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(heap1, 0); + + // Global variables. + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(&global1[0], &global2[10]); + + char *p = &small_global[0]; + foo(p, p); // OK + foo(p, p + 7); // OK + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p, p + 8); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p - 1, p); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p, p - 1); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p - 1, p + 8); + + p = &large_global[0]; + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p - 1, p); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p, p - 1); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p, &global1[0]); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p, &small_global[0]); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(p, 0); + + // Stack variables. + char stack1, stack2; + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(&stack1, &stack2); + + // Mixtures. + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(heap1, &stack1); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + foo(heap1, &global1[0]); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + foo(&stack1, &global1[0]); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-compare-errors.cc:[[@LINE+1]] + foo(&stack1, 0); + + free(heap1); + + return 0; +} diff --git a/test/asan/TestCases/invalid-pointer-pairs-compare-success.cc b/test/asan/TestCases/invalid-pointer-pairs-compare-success.cc new file mode 100644 index 000000000..565d39088 --- /dev/null +++ b/test/asan/TestCases/invalid-pointer-pairs-compare-success.cc @@ -0,0 +1,74 @@ +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair + +// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t + +#include <assert.h> +#include <stdlib.h> + +int foo(char *p) { + char *p2 = p + 20; + return p > p2; +} + +int bar(char *p, char *q) { + return p <= q; +} + +int baz(char *p, char *q) { + return p != 0 && p < q; +} + +char global[8192] = {}; +char small_global[7] = {}; + +int main() { + // Heap allocated memory. + char *p = (char *)malloc(42); + int r = foo(p); + free(p); + + p = (char *)malloc(1024); + bar(p, p + 1024); + bar(p + 1024, p + 1023); + bar(p + 1, p + 1023); + free(p); + + p = (char *)malloc(4096); + bar(p, p + 4096); + bar(p + 10, p + 100); + bar(p + 1024, p + 4096); + bar(p + 4095, p + 4096); + bar(p + 4095, p + 4094); + bar(p + 100, p + 4096); + bar(p + 100, p + 4094); + free(p); + + // Global variable. + bar(&global[0], &global[1]); + bar(&global[1], &global[2]); + bar(&global[2], &global[1]); + bar(&global[0], &global[100]); + bar(&global[1000], &global[7000]); + bar(&global[500], &global[10]); + p = &global[0]; + bar(p, p + 8192); + p = &global[8000]; + bar(p, p + 192); + + p = &small_global[0]; + bar(p, p + 1); + bar(p, p + 7); + bar(p + 7, p + 1); + bar(p + 6, p + 7); + bar(p + 7, p + 7); + + // Stack variable. + char stack[10000]; + bar(&stack[0], &stack[100]); + bar(&stack[1000], &stack[9000]); + bar(&stack[500], &stack[10]); + + baz(0, &stack[10]); + + return 0; +} diff --git a/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc b/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc new file mode 100644 index 000000000..546f61f81 --- /dev/null +++ b/test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc @@ -0,0 +1,48 @@ +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair + +// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1:halt_on_error=0 %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> + +int foo(char *p, char *q) { + return p - q; +} + +char global1[100] = {}, global2[100] = {}; + +int main() { + // Heap allocated memory. + char *heap1 = (char *)malloc(42); + char *heap2 = (char *)malloc(42); + + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cc:[[@LINE+1]] + foo(heap1, heap2); + + // Global variables. + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cc:[[@LINE+1]] + foo(&global1[0], &global2[10]); + + // Stack variables. + char stack1, stack2; + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cc:[[@LINE+1]] + foo(&stack1, &stack2); + + // Mixtures. + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cc:[[@LINE+1]] + foo(heap1, &stack1); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cc:[[@LINE+1]] + foo(heap1, &global1[0]); + // CHECK: ERROR: AddressSanitizer: invalid-pointer-pair + // CHECK: #{{[0-9]+ .*}} in main {{.*}}invalid-pointer-pairs-subtract-errors.cc:[[@LINE+1]] + foo(&stack1, &global1[0]); + + free(heap1); + free(heap2); + return 0; +} diff --git a/test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc b/test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc new file mode 100644 index 000000000..4ce484248 --- /dev/null +++ b/test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc @@ -0,0 +1,33 @@ +// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair + +// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t + +#include <assert.h> +#include <stdlib.h> + +int bar(char *p, char *q) { + return p <= q; +} + +char global[10000] = {}; + +int main() { + // Heap allocated memory. + char *p = (char *)malloc(42); + int r = bar(p, p + 20); + free(p); + + // Global variable. + bar(&global[0], &global[100]); + bar(&global[1000], &global[9000]); + bar(&global[500], &global[10]); + bar(&global[0], &global[10000]); + + // Stack variable. + char stack[10000]; + bar(&stack[0], &stack[100]); + bar(&stack[1000], &stack[9000]); + bar(&stack[500], &stack[10]); + + return 0; +} |