summaryrefslogtreecommitdiff
path: root/test/hwasan/TestCases
diff options
context:
space:
mode:
Diffstat (limited to 'test/hwasan/TestCases')
-rw-r--r--test/hwasan/TestCases/Linux/decorate-proc-maps.c59
-rw-r--r--test/hwasan/TestCases/Linux/release-shadow.c70
-rw-r--r--test/hwasan/TestCases/Linux/vfork.c32
-rw-r--r--test/hwasan/TestCases/malloc_bisect.c26
-rw-r--r--test/hwasan/TestCases/mem-intrinsics.c12
-rw-r--r--test/hwasan/TestCases/print-module-map.c32
-rw-r--r--test/hwasan/TestCases/realloc-test.cc23
-rw-r--r--test/hwasan/TestCases/register-dump-no-fp.cc28
-rw-r--r--test/hwasan/TestCases/register-dump-read.c43
-rw-r--r--test/hwasan/TestCases/sanitizer_malloc.cc1
-rw-r--r--test/hwasan/TestCases/sizes.cpp13
-rw-r--r--test/hwasan/TestCases/stack-uar.c5
-rw-r--r--test/hwasan/TestCases/tag_in_free.c51
-rw-r--r--test/hwasan/TestCases/use-after-free.c4
14 files changed, 383 insertions, 16 deletions
diff --git a/test/hwasan/TestCases/Linux/decorate-proc-maps.c b/test/hwasan/TestCases/Linux/decorate-proc-maps.c
new file mode 100644
index 000000000..8d5824091
--- /dev/null
+++ b/test/hwasan/TestCases/Linux/decorate-proc-maps.c
@@ -0,0 +1,59 @@
+// RUN: %clang_hwasan -g %s -o %t
+// RUN: %env_hwasan_opts=decorate_proc_maps=1 %run %t 2>&1 | FileCheck %s --check-prefix=A
+// RUN: %env_hwasan_opts=decorate_proc_maps=1 %run %t 2>&1 | FileCheck %s --check-prefix=B
+
+// A: rw-p {{.*}}hwasan threads]
+// A-NEXT: ---p {{.*}}shadow gap]
+// A-NEXT: rw-p {{.*}}low shadow]
+// A-NEXT: ---p {{.*}}shadow gap]
+// A-NEXT: rw-p {{.*}}high shadow]
+
+// B-DAG: rw-p {{.*}}SizeClassAllocator: region data]
+// B-DAG: rw-p {{.*}}SizeClassAllocator: region metadata]
+// B-DAG: rw-p {{.*}}SizeClassAllocator: freearray]
+// B-DAG: rw-p {{.*}}SizeClassAllocator: region info]
+// B-DAG: rw-p {{.*}}LargeMmapAllocator]
+// B-DAG: rw-p {{.*}}stack depot]
+
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+
+void CopyFdToFd(int in_fd, int out_fd) {
+ const size_t kBufSize = 0x10000;
+ static char buf[kBufSize];
+ while (1) {
+ ssize_t got = read(in_fd, buf, kBufSize);
+ if (got > 0) {
+ write(out_fd, buf, got);
+ } else if (got == 0) {
+ break;
+ } else if (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR) {
+ fprintf(stderr, "error reading file, errno %d\n", errno);
+ abort();
+ }
+ }
+}
+
+void *ThreadFn(void *arg) {
+ (void)arg;
+ int fd = open("/proc/self/maps", O_RDONLY);
+ CopyFdToFd(fd, 2);
+ close(fd);
+ return NULL;
+}
+
+int main(void) {
+ pthread_t t;
+ void * volatile res = malloc(100);
+ void * volatile res2 = malloc(100000);
+ pthread_create(&t, 0, ThreadFn, 0);
+ pthread_join(t, 0);
+ return (int)(size_t)res;
+}
diff --git a/test/hwasan/TestCases/Linux/release-shadow.c b/test/hwasan/TestCases/Linux/release-shadow.c
new file mode 100644
index 000000000..9aae35063
--- /dev/null
+++ b/test/hwasan/TestCases/Linux/release-shadow.c
@@ -0,0 +1,70 @@
+// Test that tagging a large region to 0 reduces RSS.
+// RUN: %clang_hwasan -mllvm -hwasan-instrument-stack=0 %s -o %t && %run %t 2>&1
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <sanitizer/hwasan_interface.h>
+
+const unsigned char kTag = 42;
+const size_t kNumShadowPages = 256;
+const size_t kNumPages = 16 * kNumShadowPages;
+const size_t kPageSize = 4096;
+const size_t kMapSize = kNumPages * kPageSize;
+
+void sync_rss() {
+ char *page = (char *)mmap(0, kPageSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ // Linux kernel updates RSS counters after a set number of page faults.
+ for (int i = 0; i < 1000; ++i) {
+ page[0] = 42;
+ madvise(page, kPageSize, MADV_DONTNEED);
+ }
+ munmap(page, kPageSize);
+}
+
+size_t current_rss() {
+ sync_rss();
+ int statm_fd = open("/proc/self/statm", O_RDONLY);
+ assert(statm_fd >= 0);
+
+ char buf[100];
+ assert(read(statm_fd, &buf, sizeof(buf)) > 0);
+ size_t size, rss;
+ assert(sscanf(buf, "%zu %zu", &size, &rss) == 2);
+
+ close(statm_fd);
+ return rss;
+}
+
+void test_rss_difference(void *p) {
+ __hwasan_tag_memory(p, kTag, kMapSize);
+ size_t rss_before = current_rss();
+ __hwasan_tag_memory(p, 0, kMapSize);
+ size_t rss_after = current_rss();
+ fprintf(stderr, "%zu -> %zu\n", rss_before, rss_after);
+ assert(rss_before > rss_after);
+ size_t diff = rss_before - rss_after;
+ fprintf(stderr, "diff %zu\n", diff);
+ // Check that the difference is at least close to kNumShadowPages.
+ assert(diff > kNumShadowPages / 4 * 3);
+}
+
+int main() {
+ fprintf(stderr, "starting rss %zu\n", current_rss());
+ fprintf(stderr, "shadow pages: %zu\n", kNumShadowPages);
+
+ void *p = mmap(0, kMapSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ fprintf(stderr, "p = %p\n", p);
+
+ test_rss_difference(p);
+ test_rss_difference(p);
+ test_rss_difference(p);
+
+ return 0;
+}
diff --git a/test/hwasan/TestCases/Linux/vfork.c b/test/hwasan/TestCases/Linux/vfork.c
new file mode 100644
index 000000000..84e960279
--- /dev/null
+++ b/test/hwasan/TestCases/Linux/vfork.c
@@ -0,0 +1,32 @@
+// https://github.com/google/sanitizers/issues/925
+// RUN: %clang_hwasan -O0 %s -o %t && %run %t 2>&1
+
+// REQUIRES: aarch64-target-arch || x86_64-target-arch
+
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sanitizer/hwasan_interface.h>
+
+__attribute__((noinline, no_sanitize("hwaddress"))) void child() {
+ char x[10000];
+ __hwasan_tag_memory(x, 0xAA, sizeof(x));
+ _exit(0);
+}
+
+__attribute__((noinline, no_sanitize("hwaddress"))) void parent() {
+ char x[10000];
+ __hwasan_print_shadow(&x, sizeof(x));
+ assert(__hwasan_test_shadow(x, sizeof(x)) == -1);
+}
+
+int main(int argc, char **argv) {
+ if (vfork())
+ parent();
+ else
+ child();
+
+ return 0;
+}
diff --git a/test/hwasan/TestCases/malloc_bisect.c b/test/hwasan/TestCases/malloc_bisect.c
new file mode 100644
index 000000000..51cbbfe2a
--- /dev/null
+++ b/test/hwasan/TestCases/malloc_bisect.c
@@ -0,0 +1,26 @@
+// RUN: %clang_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=malloc_bisect_left=0,malloc_bisect_right=0 not %run %t 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CRASH
+// RUN: %env_hwasan_opts=malloc_bisect_left=1000,malloc_bisect_right=999 %run %t 2>&1
+// RUN: %env_hwasan_opts=malloc_bisect_left=0,malloc_bisect_right=4294967295 not %run %t 2>&1 | \
+// RUN: FileCheck %s --check-prefix=CRASH
+// RUN: %env_hwasan_opts=malloc_bisect_left=0,malloc_bisect_right=4294967295,malloc_bisect_dump=1 not %run %t 2>&1 | \
+// RUN: FileCheck %s --check-prefixes=CRASH,DUMP
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sanitizer/hwasan_interface.h>
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+ // DUMP: [alloc] {{.*}} 10{{$}}
+ // DUMP: in main{{.*}}malloc_bisect.c
+ char * volatile p = (char*)malloc(10);
+ // CRASH: HWAddressSanitizer: tag-mismatch on address
+ // CRASH: in main{{.*}}malloc_bisect.c
+ char volatile x = p[16];
+ free(p);
+ __hwasan_disable_allocator_tagging();
+
+ return 0;
+}
diff --git a/test/hwasan/TestCases/mem-intrinsics.c b/test/hwasan/TestCases/mem-intrinsics.c
index 164bc6d93..c35d5790e 100644
--- a/test/hwasan/TestCases/mem-intrinsics.c
+++ b/test/hwasan/TestCases/mem-intrinsics.c
@@ -10,8 +10,8 @@
#include <unistd.h>
int main() {
- char Q[16];
- char P[16];
+ char Q[16] __attribute__((aligned(256)));
+ char P[16] __attribute__((aligned(256)));
#if TEST_NO == 1
memset(Q, 0, 32);
#elif TEST_NO == 2
@@ -21,15 +21,17 @@ int main() {
#endif
write(STDOUT_FILENO, "recovered\n", 10);
// WRITE: ERROR: HWAddressSanitizer: tag-mismatch on address
- // WRITE: WRITE {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
+ // WRITE: WRITE of size 32 at {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
+ // WRITE: Invalid access starting at offset [16, 32)
// WRITE: Memory tags around the buggy address (one tag corresponds to 16 bytes):
- // WRITE: =>{{.*}}[[MEM_TAG]]
+ // WRITE: =>{{.*}}[[PTR_TAG]]{{[[:space:]]\[}}[[MEM_TAG]]
// WRITE-NOT: recovered
// READ: ERROR: HWAddressSanitizer: tag-mismatch on address
+ // READ-NOT: Invalid access starting at offset
// READ: READ {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
// READ: Memory tags around the buggy address (one tag corresponds to 16 bytes):
- // READ: =>{{.*}}[[MEM_TAG]]
+ // READ: =>{{.*}}[[PTR_TAG]]{{[[:space:]]\[}}[[MEM_TAG]]
// READ-NOT: recovered
// RECOVER: recovered
diff --git a/test/hwasan/TestCases/print-module-map.c b/test/hwasan/TestCases/print-module-map.c
new file mode 100644
index 000000000..bb94aa116
--- /dev/null
+++ b/test/hwasan/TestCases/print-module-map.c
@@ -0,0 +1,32 @@
+// RUN: %clang_hwasan %s -o %t && %env_hwasan_opts=print_module_map=1 %run %t 2>&1 | FileCheck %s --check-prefixes=EXIT,NOMORE
+// RUN: %clang_hwasan %s -DBUG -o %t && %env_hwasan_opts=print_module_map=1 not %run %t 2>&1 | FileCheck %s --check-prefixes=EXIT,NOMORE
+// RUN: %clang_hwasan %s -DBUG -fsanitize-recover=hwaddress -o %t && %env_hwasan_opts=print_module_map=1,halt_on_error=0 not %run %t 2>&1 | FileCheck %s --check-prefixes=EXIT,NOMORE
+// RUN: %clang_hwasan %s -DBUG -fsanitize-recover=hwaddress -o %t && %env_hwasan_opts=print_module_map=2,halt_on_error=0 not %run %t 2>&1 | FileCheck %s --check-prefixes=BUG1,BUG2,EXIT,NOMORE
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sanitizer/hwasan_interface.h>
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+#ifdef BUG
+ char * volatile x = (char*)malloc(40);
+ free(x);
+ free(x);
+ free(x);
+#endif
+ __hwasan_disable_allocator_tagging();
+ // BUG1: Process memory map follows:
+ // BUG1: print-module-map
+ // BUG1: End of process memory map.
+
+ // BUG2: Process memory map follows:
+ // BUG2: print-module-map
+ // BUG2: End of process memory map.
+
+ // EXIT: Process memory map follows:
+ // EXIT: print-module-map
+ // EXIT: End of process memory map.
+
+ // NOMORE-NOT: Process memory map follows:
+}
diff --git a/test/hwasan/TestCases/realloc-test.cc b/test/hwasan/TestCases/realloc-test.cc
index 838790242..136346f57 100644
--- a/test/hwasan/TestCases/realloc-test.cc
+++ b/test/hwasan/TestCases/realloc-test.cc
@@ -1,36 +1,43 @@
// Test basic realloc functionality.
-// RUN: %clang_hwasan %s -o %t
-// RUN: %run %t
+// RUN: %clang_hwasan %s -o %t && %run %t
+// RUN: %clang_hwasan %s -DREALLOCARRAY -o %t && %run %t
-#include <stdlib.h>
#include <assert.h>
#include <sanitizer/hwasan_interface.h>
+#ifdef REALLOCARRAY
+extern "C" void *reallocarray(void *, size_t nmemb, size_t size);
+#define REALLOC(p, s) reallocarray(p, 1, s)
+#else
+#include <stdlib.h>
+#define REALLOC(p, s) realloc(p, s)
+#endif
+
int main() {
__hwasan_enable_allocator_tagging();
- char *x = (char*)realloc(nullptr, 4);
+ char *x = (char*)REALLOC(nullptr, 4);
x[0] = 10;
x[1] = 20;
x[2] = 30;
x[3] = 40;
- char *x1 = (char*)realloc(x, 5);
+ char *x1 = (char*)REALLOC(x, 5);
assert(x1 != x); // not necessary true for C,
// but true today for hwasan.
assert(x1[0] == 10 && x1[1] == 20 && x1[2] == 30 && x1[3] == 40);
x1[4] = 50;
- char *x2 = (char*)realloc(x1, 6);
+ char *x2 = (char*)REALLOC(x1, 6);
x2[5] = 60;
assert(x2 != x1);
assert(x2[0] == 10 && x2[1] == 20 && x2[2] == 30 && x2[3] == 40 &&
x2[4] == 50 && x2[5] == 60);
- char *x3 = (char*)realloc(x2, 6);
+ char *x3 = (char*)REALLOC(x2, 6);
assert(x3 != x2);
assert(x3[0] == 10 && x3[1] == 20 && x3[2] == 30 && x3[3] == 40 &&
x3[4] == 50 && x3[5] == 60);
- char *x4 = (char*)realloc(x3, 5);
+ char *x4 = (char*)REALLOC(x3, 5);
assert(x4 != x3);
assert(x4[0] == 10 && x4[1] == 20 && x4[2] == 30 && x4[3] == 40 &&
x4[4] == 50);
diff --git a/test/hwasan/TestCases/register-dump-no-fp.cc b/test/hwasan/TestCases/register-dump-no-fp.cc
new file mode 100644
index 000000000..1a14cab0a
--- /dev/null
+++ b/test/hwasan/TestCases/register-dump-no-fp.cc
@@ -0,0 +1,28 @@
+// RUN: %clangxx_hwasan -fomit-frame-pointer -momit-leaf-frame-pointer \
+// RUN: -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clangxx_hwasan -fomit-frame-pointer -momit-leaf-frame-pointer \
+// RUN: -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clangxx_hwasan -fomit-frame-pointer -momit-leaf-frame-pointer \
+// RUN: -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clangxx_hwasan -fomit-frame-pointer -momit-leaf-frame-pointer \
+// RUN: -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+
+// This test ensures that the CFA is implemented properly for slow
+// (non-frame-pointer) unwinding.
+#include <sanitizer/hwasan_interface.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+__attribute__((noinline)) void f(int *p) { *p = 3; }
+
+// CHECK: ERROR: HWAddressSanitizer:
+// CHECK: #0 {{.*}} in f(int*) {{.*}}register-dump-no-fp.cc:[[@LINE-3]]
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+
+ int *volatile a = new int;
+ a = (int *)__hwasan_tag_pointer(a, 0);
+ f(a);
+ // CHECK: #1 {{.*}} in main {{.*}}register-dump-no-fp.cc:[[@LINE-1]]
+}
diff --git a/test/hwasan/TestCases/register-dump-read.c b/test/hwasan/TestCases/register-dump-read.c
new file mode 100644
index 000000000..19bf03f5d
--- /dev/null
+++ b/test/hwasan/TestCases/register-dump-read.c
@@ -0,0 +1,43 @@
+// RUN: %clang_hwasan -ffixed-x10 -ffixed-x20 -ffixed-x27 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_hwasan -ffixed-x10 -ffixed-x20 -ffixed-x27 -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_hwasan -ffixed-x10 -ffixed-x20 -ffixed-x27 -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_hwasan -ffixed-x10 -ffixed-x20 -ffixed-x27 -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// REQUIRES: aarch64-target-arch
+
+// RUN: %clang_hwasan -ffixed-x10 -ffixed-x20 -ffixed-x27 -O2 %s -o %t && not %env_hwasan_opts=fast_unwind_on_fatal=true %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+// RUN: %clang_hwasan -ffixed-x10 -ffixed-x20 -ffixed-x27 -O2 %s -o %t && not %env_hwasan_opts=fast_unwind_on_fatal=false %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sanitizer/hwasan_interface.h>
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+ char * volatile x = (char*) malloc(10);
+ asm volatile("mov x10, #0x2222\n"
+ "mov x20, #0x3333\n"
+ "mov x27, #0x4444\n");
+ return x[16];
+
+ // CHECK: ERROR: HWAddressSanitizer:
+ // CHECK: #0 {{.*}} in main {{.*}}register-dump-read.c:[[@LINE-3]]
+
+ // Developer note: FileCheck really doesn't like when you have a regex that
+ // ends with a '}' character, e.g. the regex "[0-9]{10}" will fail, because
+ // the closing '}' fails as an "unbalanced regex". We work around this by
+ // encasing the trailing space after a register, or the end-of-line specifier.
+
+ // CHECK: Registers where the failure occurred
+ // CHECK-NEXT: x0{{[ ]+[0-9a-f]{16}[ ]}}x1{{[ ]+[0-9a-f]{16}[ ]}}x2{{[ ]+[0-9a-f]{16}[ ]}}x3{{[ ]+[0-9a-f]{16}$}}
+ // CHECK-NEXT: x4{{[ ]+[0-9a-f]{16}[ ]}}x5{{[ ]+[0-9a-f]{16}[ ]}}x6{{[ ]+[0-9a-f]{16}[ ]}}x7{{[ ]+[0-9a-f]{16}$}}
+ // CHECK-NEXT: x8{{[ ]+[0-9a-f]{16}[ ]}}x9{{[ ]+[0-9a-f]{16}[ ]}}
+ // CHECK-SAME: x10 0000000000002222
+ // CHECK-SAME: x11{{[ ]+[0-9a-f]{16}$}}
+ // CHECK-NEXT: x12{{[ ]+[0-9a-f]{16}[ ]}}x13{{[ ]+[0-9a-f]{16}[ ]}}x14{{[ ]+[0-9a-f]{16}[ ]}}x15{{[ ]+[0-9a-f]{16}$}}
+ // CHECK-NEXT: x16{{[ ]+[0-9a-f]{16}[ ]}}x17{{[ ]+[0-9a-f]{16}[ ]}}x18{{[ ]+[0-9a-f]{16}[ ]}}x19{{[ ]+[0-9a-f]{16}$}}
+ // CHECK-NEXT: x20 0000000000003333
+ // CHECK-SAME: x21{{[ ]+[0-9a-f]{16}[ ]}}x22{{[ ]+[0-9a-f]{16}[ ]}}x23{{[ ]+[0-9a-f]{16}$}}
+ // CHECK-NEXT: x24{{[ ]+[0-9a-f]{16}[ ]}}x25{{[ ]+[0-9a-f]{16}[ ]}}x26{{[ ]+[0-9a-f]{16}[ ]}}
+ // CHECK-SAME: x27 0000000000004444
+ // CHECK-NEXT: x28{{[ ]+[0-9a-f]{16}[ ]}}x29{{[ ]+[0-9a-f]{16}[ ]}}x30{{[ ]+[0-9a-f]{16}$}}
+}
diff --git a/test/hwasan/TestCases/sanitizer_malloc.cc b/test/hwasan/TestCases/sanitizer_malloc.cc
index 66ac9641e..cf1dc0741 100644
--- a/test/hwasan/TestCases/sanitizer_malloc.cc
+++ b/test/hwasan/TestCases/sanitizer_malloc.cc
@@ -20,6 +20,7 @@ int main() {
sink = (void *)&__sanitizer_malloc_stats;
sink = (void *)&__sanitizer_calloc;
sink = (void *)&__sanitizer_realloc;
+ sink = (void *)&__sanitizer_reallocarray;
sink = (void *)&__sanitizer_malloc;
// sanity check
diff --git a/test/hwasan/TestCases/sizes.cpp b/test/hwasan/TestCases/sizes.cpp
index 52217de74..102a85f17 100644
--- a/test/hwasan/TestCases/sizes.cpp
+++ b/test/hwasan/TestCases/sizes.cpp
@@ -1,10 +1,14 @@
-// RUN: %clangxx_hwasan %s -lstdc++ -o %t
+// This test requires operator new to be intercepted by the hwasan runtime,
+// so we need to avoid linking against libc++.
+// RUN: %clangxx_hwasan %s -nostdlib++ -lstdc++ -o %t
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-max
// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t malloc 2>&1
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t malloc max 2>&1 | FileCheck %s --check-prefix=CHECK-max
// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t malloc max 2>&1
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-calloc
// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t calloc 2>&1
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t reallocarray 2>&1 | FileCheck %s --check-prefix=CHECK-reallocarray
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t reallocarray 2>&1
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-max
// RUN: %env_hwasan_opts=allocator_may_return_null=1 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-oom
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new max 2>&1 | FileCheck %s --check-prefix=CHECK-max
@@ -28,6 +32,7 @@
#include <new>
#include <sanitizer/allocator_interface.h>
+#include <sanitizer/hwasan_interface.h>
int main(int argc, char **argv) {
assert(argc <= 3);
@@ -49,6 +54,11 @@ int main(int argc, char **argv) {
size_t size = std::numeric_limits<size_t>::max();
void *p = calloc((size / 0x1000) + 1, 0x1000);
assert(!p);
+ } else if (!strcmp(argv[1], "reallocarray")) {
+ // Trigger an overflow in reallocarray.
+ size_t size = std::numeric_limits<size_t>::max();
+ void *p = __sanitizer_reallocarray(nullptr, (size / 0x1000) + 1, 0x1000);
+ assert(!p);
} else if (!strcmp(argv[1], "new")) {
void *p = operator new(MallocSize);
assert(!p);
@@ -78,3 +88,4 @@ int main(int argc, char **argv) {
// CHECK-max: {{ERROR: HWAddressSanitizer: requested allocation size .* exceeds maximum supported size}}
// CHECK-oom: ERROR: HWAddressSanitizer: allocator is out of memory
// CHECK-calloc: ERROR: HWAddressSanitizer: calloc parameters overflow
+// CHECK-reallocarray: ERROR: HWAddressSanitizer: reallocarray parameters overflow
diff --git a/test/hwasan/TestCases/stack-uar.c b/test/hwasan/TestCases/stack-uar.c
index 863a84017..8b308a511 100644
--- a/test/hwasan/TestCases/stack-uar.c
+++ b/test/hwasan/TestCases/stack-uar.c
@@ -1,5 +1,6 @@
// 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
+// RUN: %clang_hwasan -O0 -fno-discard-value-names %s -o %t && not %env_hwasan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
// REQUIRES: stable-runtime
@@ -37,5 +38,9 @@ int main() {
// CHECK: buggy
// CHECK: 4096 zzz
+ // NOSYM: Previously allocated frames:
+ // NOSYM-NEXT: sp: 0x{{.*}} #0 0x{{.*}} ({{.*}}/stack-uar.c.tmp+0x{{.*}}){{$}}
+ // NOSYM-NEXT: 16 CCC;
+
// CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main
}
diff --git a/test/hwasan/TestCases/tag_in_free.c b/test/hwasan/TestCases/tag_in_free.c
new file mode 100644
index 000000000..51e8d015d
--- /dev/null
+++ b/test/hwasan/TestCases/tag_in_free.c
@@ -0,0 +1,51 @@
+// RUN: %clang_hwasan -O0 %s -DMALLOC -DFREE -o %t.mf
+// RUN: %env_hwasan_opts=tag_in_malloc=0,tag_in_free=1 not %run %t.mf 2>&1 | FileCheck %s --check-prefixes=FREE
+// RUN: %env_hwasan_opts=tag_in_malloc=1,tag_in_free=1 not %run %t.mf 2>&1 | FileCheck %s --check-prefixes=MALLOC
+// RUN: %env_hwasan_opts=tag_in_malloc=1,tag_in_free=0 not %run %t.mf 2>&1 | FileCheck %s --check-prefixes=MALLOC
+// RUN: %env_hwasan_opts=tag_in_malloc=0,tag_in_free=0 %run %t.mf 2>&1
+
+// RUN: %clang_hwasan -O0 %s -DFREE -o %t.f
+// RUN: %env_hwasan_opts=tag_in_malloc=0,tag_in_free=1 not %run %t.f 2>&1 | FileCheck %s --check-prefixes=FREE
+// RUN: %env_hwasan_opts=tag_in_malloc=1,tag_in_free=1 not %run %t.f 2>&1 | FileCheck %s --check-prefixes=FREE
+// RUN: %env_hwasan_opts=tag_in_malloc=1,tag_in_free=0 %run %t.f 2>&1
+// RUN: %env_hwasan_opts=tag_in_malloc=0,tag_in_free=0 %run %t.f 2>&1
+
+// RUN: %clang_hwasan -O0 %s -DMALLOC -o %t.m
+// RUN: %env_hwasan_opts=tag_in_malloc=0,tag_in_free=1 %run %t.m 2>&1
+// RUN: %env_hwasan_opts=tag_in_malloc=1,tag_in_free=1 not %run %t.m 2>&1 | FileCheck %s --check-prefixes=MALLOC
+// RUN: %env_hwasan_opts=tag_in_malloc=1,tag_in_free=0 not %run %t.m 2>&1 | FileCheck %s --check-prefixes=MALLOC
+// RUN: %env_hwasan_opts=tag_in_malloc=0,tag_in_free=0 %run %t.m 2>&1
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sanitizer/hwasan_interface.h>
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+ // Loop for a while to make sure that the memory for the test below is reused after an earlier free(),
+ // and is potentially tagged (when tag_in_free == 1).
+ for (int i = 0; i < 100; ++i) {
+ char * volatile p = (char*)malloc(10);
+ free(p);
+ }
+
+ char * volatile p = (char*)malloc(10);
+#ifdef MALLOC
+ // MALLOC: READ of size 1 at
+ // MALLOC: is located 6 bytes to the right of 10-byte region
+ // MALLOC: allocated here:
+ char volatile x = p[16];
+#endif
+ free(p);
+#ifdef FREE
+ // FREE: READ of size 1 at
+ // FREE: is located 0 bytes inside of 10-byte region
+ // FREE: freed by thread T0 here:
+ // FREE: previously allocated here:
+ char volatile y = p[0];
+#endif
+
+ __hwasan_disable_allocator_tagging();
+
+ return 0;
+}
diff --git a/test/hwasan/TestCases/use-after-free.c b/test/hwasan/TestCases/use-after-free.c
index 03a1771c1..269985740 100644
--- a/test/hwasan/TestCases/use-after-free.c
+++ b/test/hwasan/TestCases/use-after-free.c
@@ -27,11 +27,11 @@ int main() {
// CHECK: is located 5 bytes inside of 10-byte region
//
// CHECK: freed by thread {{.*}} here:
- // CHECK: #0 {{.*}} in {{.*}}free{{.*}} {{.*}}hwasan_interceptors.cc
+ // CHECK: #0 {{.*}} in {{.*}}free{{.*}} {{.*}}hwasan_interceptors.cpp
// CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-14]]
// CHECK: previously allocated here:
- // CHECK: #0 {{.*}} in {{.*}}malloc{{.*}} {{.*}}hwasan_interceptors.cc
+ // CHECK: #0 {{.*}} in {{.*}}malloc{{.*}} {{.*}}hwasan_interceptors.cpp
// 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]]