summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlex Shlyapnikov <alekseys@google.com>2017-12-04 18:00:24 +0000
committerAlex Shlyapnikov <alekseys@google.com>2017-12-04 18:00:24 +0000
commit1ce8e22e8474d244b05bb842ef54e9d5af7188bc (patch)
treecabc1a5ab34ed91fd5f334b48a5ec4add8aad7b0 /test
parent5551897294887d632c71275cf11c5654fd80cda7 (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')
-rw-r--r--test/asan/TestCases/Posix/invalid-pointer-pairs-threads.cc54
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-compare-errors.cc103
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-compare-success.cc74
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-subtract-errors.cc48
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs-subtract-success.cc33
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;
+}