diff options
Diffstat (limited to 'test/hwasan')
-rw-r--r-- | test/hwasan/TestCases/abort-message-android.cc | 28 | ||||
-rw-r--r-- | test/hwasan/TestCases/cfi.cc | 18 | ||||
-rw-r--r-- | test/hwasan/TestCases/heap-buffer-overflow.c | 45 | ||||
-rw-r--r-- | test/hwasan/TestCases/random-align-right.c | 35 | ||||
-rw-r--r-- | test/hwasan/TestCases/stack-history-length.c | 10 | ||||
-rw-r--r-- | test/hwasan/TestCases/stack-uar.c | 36 | ||||
-rw-r--r-- | test/hwasan/TestCases/tail-magic.c | 28 | ||||
-rw-r--r-- | test/hwasan/TestCases/thread-uaf.c | 2 | ||||
-rw-r--r-- | test/hwasan/TestCases/use-after-free.c | 9 |
9 files changed, 189 insertions, 22 deletions
diff --git a/test/hwasan/TestCases/abort-message-android.cc b/test/hwasan/TestCases/abort-message-android.cc new file mode 100644 index 000000000..f89b929d4 --- /dev/null +++ b/test/hwasan/TestCases/abort-message-android.cc @@ -0,0 +1,28 @@ +// RUN: %clangxx_hwasan -DERR=1 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_hwasan -DERR=2 %s -o %t && not %run %t 2>&1 | FileCheck %s +// REQUIRES: android + +#include <stdlib.h> +#include <stdio.h> + +#include <sanitizer/hwasan_interface.h> + +__attribute__((no_sanitize("hwaddress"))) +extern "C" void android_set_abort_message(const char *msg) { + fprintf(stderr, "== abort message start\n%s\n== abort message end\n", msg); +} + +int main() { + __hwasan_enable_allocator_tagging(); + char *volatile p = (char *)malloc(16); + if (ERR==1) { + p[16] = 1; + } else { + free(p); + free(p); + } + // CHECK: ERROR: HWAddressSanitizer: + // CHECK: == abort message start + // CHECK: ERROR: HWAddressSanitizer: + // CHECK: == abort message end +} diff --git a/test/hwasan/TestCases/cfi.cc b/test/hwasan/TestCases/cfi.cc new file mode 100644 index 000000000..457e29659 --- /dev/null +++ b/test/hwasan/TestCases/cfi.cc @@ -0,0 +1,18 @@ +// RUN: %clang_hwasan -fsanitize=cfi -fno-sanitize-trap=cfi -flto -fvisibility=hidden -fuse-ld=lld %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s + +// REQUIRES: android + +// Smoke test for CFI + HWASAN. + +struct A { + virtual void f(); +}; + +void A::f() {} + +int main() { + // CHECK: control flow integrity check for type {{.*}} failed during cast to unrelated type + A *a = reinterpret_cast<A *>(reinterpret_cast<void *>(&main)); + (void)a; +} diff --git a/test/hwasan/TestCases/heap-buffer-overflow.c b/test/hwasan/TestCases/heap-buffer-overflow.c index 40b6e6e9d..bff39d293 100644 --- a/test/hwasan/TestCases/heap-buffer-overflow.c +++ b/test/hwasan/TestCases/heap-buffer-overflow.c @@ -1,26 +1,61 @@ // RUN: %clang_hwasan %s -o %t -// RUN: not %run %t 40 2>&1 | FileCheck %s --check-prefix=CHECK40 -// RUN: not %run %t 80 2>&1 | FileCheck %s --check-prefix=CHECK80 +// RUN: not %run %t 40 2>&1 | FileCheck %s --check-prefix=CHECK40-LEFT +// RUN: %env_hwasan_opts=malloc_align_right=2 not %run %t 40 2>&1 | FileCheck %s --check-prefix=CHECK40-RIGHT +// RUN: not %run %t 80 2>&1 | FileCheck %s --check-prefix=CHECK80-LEFT +// RUN: %env_hwasan_opts=malloc_align_right=2 not %run %t 80 2>&1 | FileCheck %s --check-prefix=CHECK80-RIGHT // RUN: not %run %t -30 2>&1 | FileCheck %s --check-prefix=CHECKm30 // RUN: not %run %t -30 1000000 2>&1 | FileCheck %s --check-prefix=CHECKMm30 // RUN: not %run %t 1000000 1000000 2>&1 | FileCheck %s --check-prefix=CHECKM +// Test OOB within the granule. +// Misses the bug when malloc is left-aligned, catches it otherwise. +// RUN: %run %t 31 +// RUN: %env_hwasan_opts=malloc_align_right=2 not %run %t 31 2>&1 | FileCheck %s --check-prefix=CHECK31 + +// RUN: %run %t 30 20 +// RUN: %env_hwasan_opts=malloc_align_right=9 not %run %t 30 20 2>&1 | FileCheck %s --check-prefix=CHECK20-RIGHT8 + +// RUN: %env_hwasan_opts=malloc_align_right=42 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-WRONG-FLAG + // REQUIRES: stable-runtime #include <stdlib.h> #include <stdio.h> #include <sanitizer/hwasan_interface.h> +static volatile char sink; + int main(int argc, char **argv) { __hwasan_enable_allocator_tagging(); int offset = argc < 2 ? 40 : atoi(argv[1]); int size = argc < 3 ? 30 : atoi(argv[2]); char * volatile x = (char*)malloc(size); - x[offset] = 42; -// CHECK40: is located 10 bytes to the right of 30-byte region -// CHECK80: is located 50 bytes to the right of 30-byte region + fprintf(stderr, "base: %p access: %p\n", x, &x[offset]); + sink = x[offset]; + +// CHECK40-LEFT: allocated heap chunk; size: 32 offset: 8 +// CHECK40-LEFT: is located 10 bytes to the right of 30-byte region +// CHECK40-RIGHT: allocated heap chunk; size: 32 offset: +// CHECK40-RIGHT: is located 10 bytes to the right of 30-byte region +// +// CHECK80-LEFT: allocated heap chunk; size: 32 offset: 16 +// CHECK80-LEFT: is located 50 bytes to the right of 30-byte region +// CHECK80-RIGHT: allocated heap chunk; size: 32 offset: +// CHECK80-RIGHT: is located 50 bytes to the right of 30-byte region +// +// CHECKm30: allocated heap chunk; size: 32 offset: 2 // CHECKm30: is located 30 bytes to the left of 30-byte region +// +// CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30 // CHECKMm30: is located 30 bytes to the left of 1000000-byte region +// +// CHECKM: is a large allocated heap chunk; size: 1003520 offset: 1000000 // CHECKM: is located 0 bytes to the right of 1000000-byte region +// +// CHECK31: is located 1 bytes to the right of 30-byte region +// +// CHECK20-RIGHT8: is located 10 bytes to the right of 20-byte region [0x{{.*}}8,0x{{.*}}c) +// +// CHECK-WRONG-FLAG: ERROR: unsupported value of malloc_align_right flag: 42 free(x); } diff --git a/test/hwasan/TestCases/random-align-right.c b/test/hwasan/TestCases/random-align-right.c new file mode 100644 index 000000000..8c524ef47 --- /dev/null +++ b/test/hwasan/TestCases/random-align-right.c @@ -0,0 +1,35 @@ +// Tests malloc_align_right=1 and 8 (randomly aligning right). +// RUN: %clang_hwasan %s -o %t +// +// RUN: %run %t +// RUN: %env_hwasan_opts=malloc_align_right=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %env_hwasan_opts=malloc_align_right=8 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK8 + +// REQUIRES: stable-runtime + +#include <stdlib.h> +#include <stdio.h> +#include <sanitizer/hwasan_interface.h> + +static volatile void *sink; + +int main(int argc, char **argv) { + __hwasan_enable_allocator_tagging(); + + // Perform 1000 buffer overflows within the 16-byte granule, + // so that random right-alignment has a very high chance of + // catching at least one of them. + for (int i = 0; i < 1000; i++) { + char *p = (char*)malloc(20); + sink = p; + fprintf(stderr, "[%d] p: %p; accessing p[20]:\n", i, p); + p[20 * argc] = 0; // requires malloc_align_right=1 to catch + fprintf(stderr, "[%d] p: %p; accessing p[30]:\n", i, p); + p[30 * argc] = 0; // requires malloc_align_right={1,8} to catch +// CHECK1: accessing p[20] +// CHECK1-NEXT: HWAddressSanitizer: tag-mismatch +// CHECK8: accessing p[30]: +// CHECK8-NEXT: HWAddressSanitizer: tag-mismatch + } +} + diff --git a/test/hwasan/TestCases/stack-history-length.c b/test/hwasan/TestCases/stack-history-length.c index f4c0b036f..c8583c67c 100644 --- a/test/hwasan/TestCases/stack-history-length.c +++ b/test/hwasan/TestCases/stack-history-length.c @@ -1,7 +1,6 @@ -// RUN: %clang_hwasan -O1 -DX=2046 %s -o %t.2046 -// RUN: %clang_hwasan -O1 -DX=2047 %s -o %t.2047 -// RUN: %env_hwasan_opts=stack_history_size=2048 not %run %t.2046 2>&1 | FileCheck %s --check-prefix=YES -// RUN: %env_hwasan_opts=stack_history_size=2048 not %run %t.2047 2>&1 | FileCheck %s --check-prefix=NO +// RUN: %clang_hwasan -O1 %s -o %t +// RUN: %env_hwasan_opts=stack_history_size=2048 not %run %t 2046 2>&1 | FileCheck %s --check-prefix=YES +// RUN: %env_hwasan_opts=stack_history_size=2048 not %run %t 2047 2>&1 | FileCheck %s --check-prefix=NO // REQUIRES: stable-runtime @@ -16,7 +15,8 @@ __attribute__((noinline)) void FUNC0() { int x[4]; USE(&x[0]); } __attribute__((noinline)) void FUNC() { int x[4]; USE(&x[0]); } __attribute__((noinline)) void OOB() { int x[4]; x[four] = 0; USE(&x[0]); } -int main() { +int main(int argc, char **argv) { + int X = argc == 2 ? atoi(argv[1]) : 10; // FUNC0 is X+2's element of the ring buffer. // If runtime buffer size is less than it, FUNC0 record will be lost. FUNC0(); diff --git a/test/hwasan/TestCases/stack-uar.c b/test/hwasan/TestCases/stack-uar.c index 2c59b1785..0b1faf8b5 100644 --- a/test/hwasan/TestCases/stack-uar.c +++ b/test/hwasan/TestCases/stack-uar.c @@ -1,23 +1,41 @@ -// RUN: %clang_hwasan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// Tests use-after-return detection and reporting. +// RUN: %clang_hwasan -O0 -fno-discard-value-names %s -o %t && not %run %t 2>&1 | FileCheck %s // REQUIRES: stable-runtime -#include <stdlib.h> -#include <sanitizer/hwasan_interface.h> +void USE(void *x) { // pretend_to_do_something(void *x) + __asm__ __volatile__("" : : "r" (x) : "memory"); +} __attribute__((noinline)) -char *f() { - char z[0x1000]; - char *volatile p = z; +char *buggy() { + char zzz[0x1000]; + char *volatile p = zzz; return p; } +__attribute__((noinline)) void Unrelated1() { int A[2]; USE(&A[0]); } +__attribute__((noinline)) void Unrelated2() { int BB[3]; USE(&BB[0]); } +__attribute__((noinline)) void Unrelated3() { int CCC[4]; USE(&CCC[0]); } + int main() { - return *f(); + char *p = buggy(); + Unrelated1(); + Unrelated2(); + Unrelated3(); + return *p; // CHECK: READ of size 1 at - // CHECK: #0 {{.*}} in main{{.*}}stack-uar.c:16 - + // CHECK: #0 {{.*}} in main{{.*}}stack-uar.c:[[@LINE-2]] // CHECK: is located in stack of thread + // CHECK: Previosly allocated frames: + // CHECK: Unrelated3 + // CHECK: 16 CCC + // CHECK: Unrelated2 + // CHECK: 12 BB + // CHECK: Unrelated1 + // CHECK: 8 A + // CHECK: buggy + // CHECK: 4096 zzz // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main } diff --git a/test/hwasan/TestCases/tail-magic.c b/test/hwasan/TestCases/tail-magic.c new file mode 100644 index 000000000..95c5ada08 --- /dev/null +++ b/test/hwasan/TestCases/tail-magic.c @@ -0,0 +1,28 @@ +// Tests free_checks_tail_magic=1. +// RUN: %clang_hwasan %s -o %t +// RUN: %env_hwasan_opts=free_checks_tail_magic=0 %run %t +// RUN: %env_hwasan_opts=free_checks_tail_magic=1 not %run %t 2>&1 | FileCheck %s +// RUN: not %run %t 2>&1 | FileCheck %s + +// REQUIRES: stable-runtime + +#include <stdlib.h> +#include <stdio.h> +#include <sanitizer/hwasan_interface.h> + +static volatile void *sink; + +int main(int argc, char **argv) { + __hwasan_enable_allocator_tagging(); + + char *p = (char*)malloc(20); + sink = p; + p[20] = 0x42; + p[24] = 0x66; + free(p); +// CHECK: ERROR: HWAddressSanitizer: alocation-tail-overwritten; heap object [{{.*}}) of size 20 +// CHECK: in main {{.*}}tail-magic.c:[[@LINE-2]] +// CHECK: allocated here: +// CHECK: in main {{.*}}tail-magic.c:[[@LINE-8]] +// CHECK: Tail contains: .. .. .. .. 42 {{.. .. ..}} 66 +} diff --git a/test/hwasan/TestCases/thread-uaf.c b/test/hwasan/TestCases/thread-uaf.c index 33cea1018..f091167e3 100644 --- a/test/hwasan/TestCases/thread-uaf.c +++ b/test/hwasan/TestCases/thread-uaf.c @@ -36,6 +36,8 @@ void *Use(void *arg) { // CHECK: in Allocate // CHECK: Thread: T2 0x // CHECK: Thread: T3 0x + // CHECK-DAG: Thread: T0 0x + // CHECK-DAG: Thread: T1 0x __sync_fetch_and_add(&state, 1); return NULL; } diff --git a/test/hwasan/TestCases/use-after-free.c b/test/hwasan/TestCases/use-after-free.c index 3dae97b0c..fcdd0771c 100644 --- a/test/hwasan/TestCases/use-after-free.c +++ b/test/hwasan/TestCases/use-after-free.c @@ -22,14 +22,17 @@ int main() { if (ISREAD) r = x[5]; else x[5] = 42; // should be on the same line. // CHECK: [[TYPE]] of size 1 at {{.*}} tags: [[PTR_TAG:[0-9a-f][0-9a-f]]]/[[MEM_TAG:[0-9a-f][0-9a-f]]] (ptr/mem) // CHECK: #0 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]] - + // Offset is 5 or 11 depending on left/right alignment. + // CHECK: is a small unallocated heap chunk; size: 16 offset: {{5|11}} + // CHECK: is located 5 bytes inside of 10-byte region + // // CHECK: freed by thread {{.*}} here: // CHECK: #0 {{.*}} in {{.*}}free{{.*}} {{.*}}hwasan_interceptors.cc - // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-11]] + // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-14]] // CHECK: previously allocated here: // CHECK: #0 {{.*}} in {{.*}}malloc{{.*}} {{.*}}hwasan_interceptors.cc - // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-16]] + // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-19]] // CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes): // CHECK: =>{{.*}}[[MEM_TAG]] // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main |