Index: compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cpp =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cpp +++ compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cpp @@ -9,6 +9,8 @@ #include #include +#include "../utils.h" + extern void *aligned_alloc(size_t alignment, size_t size); int main() { @@ -18,7 +20,7 @@ // CHECK: {{#1 0x.* in main .*aligned_alloc-alignment.cpp:}}[[@LINE-3]] // CHECK: SUMMARY: HWAddressSanitizer: invalid-aligned-alloc-alignment - printf("pointer after failed aligned_alloc: %zd\n", (size_t)p); + untag_printf("pointer after failed aligned_alloc: %zd\n", (size_t)p); // CHECK-NULL: pointer after failed aligned_alloc: 0 return 0; Index: compiler-rt/trunk/test/hwasan/TestCases/Linux/decorate-proc-maps.c =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/Linux/decorate-proc-maps.c +++ compiler-rt/trunk/test/hwasan/TestCases/Linux/decorate-proc-maps.c @@ -25,17 +25,19 @@ #include #include +#include "../utils.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); + ssize_t got = read(in_fd, UNTAG(buf), kBufSize); if (got > 0) { - write(out_fd, buf, got); + write(out_fd, UNTAG(buf), got); } else if (got == 0) { break; } else if (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR) { - fprintf(stderr, "error reading file, errno %d\n", errno); + untag_fprintf(stderr, "error reading file, errno %d\n", errno); abort(); } } @@ -43,7 +45,7 @@ void *ThreadFn(void *arg) { (void)arg; - int fd = open("/proc/self/maps", O_RDONLY); + int fd = open(UNTAG("/proc/self/maps"), O_RDONLY); CopyFdToFd(fd, 2); close(fd); return NULL; Index: compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cpp =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cpp +++ compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cpp @@ -18,6 +18,8 @@ #include #include +#include "../utils.h" + int main(int argc, char *argv[]) { assert(argc == 2); const char *action = argv[1]; @@ -25,15 +27,15 @@ const size_t page_size = sysconf(_SC_PAGESIZE); void *p = nullptr; - if (!strcmp(action, "m1")) { + if (!untag_strcmp(action, "m1")) { p = pvalloc((uintptr_t)-1); - } else if (!strcmp(action, "psm1")) { + } else if (!untag_strcmp(action, "psm1")) { p = pvalloc((uintptr_t)-(page_size - 1)); } else { assert(0); } - fprintf(stderr, "errno: %d\n", errno); + untag_fprintf(stderr, "errno: %d\n", errno); return p != nullptr; } Index: compiler-rt/trunk/test/hwasan/TestCases/Linux/release-shadow.c =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/Linux/release-shadow.c +++ compiler-rt/trunk/test/hwasan/TestCases/Linux/release-shadow.c @@ -12,6 +12,8 @@ #include +#include "../utils.h" + const unsigned char kTag = 42; const size_t kNumShadowPages = 256; const size_t kNumPages = 16 * kNumShadowPages; @@ -30,13 +32,13 @@ size_t current_rss() { sync_rss(); - int statm_fd = open("/proc/self/statm", O_RDONLY); + int statm_fd = open(UNTAG("/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); + assert(sscanf(buf, UNTAG("%zu %zu"), &size, &rss) == 2); close(statm_fd); return rss; @@ -47,20 +49,20 @@ 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); + untag_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); + untag_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); + untag_fprintf(stderr, "starting rss %zu\n", current_rss()); + untag_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); + untag_fprintf(stderr, "p = %p\n", p); test_rss_difference(p); test_rss_difference(p); Index: compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cpp =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cpp +++ compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cpp @@ -7,6 +7,8 @@ #include #include +#include "../utils.h" + int main() { void *p = reinterpret_cast(42); int res = posix_memalign(&p, 17, 100); @@ -15,7 +17,7 @@ // CHECK: {{#1 0x.* in main .*posix_memalign-alignment.cpp:}}[[@LINE-3]] // CHECK: SUMMARY: HWAddressSanitizer: invalid-posix-memalign-alignment - printf("pointer after failed posix_memalign: %zd\n", (size_t)p); + untag_printf("pointer after failed posix_memalign: %zd\n", (size_t)p); // CHECK-NULL: pointer after failed posix_memalign: 42 return 0; Index: compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cpp =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cpp +++ compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cpp @@ -48,40 +48,42 @@ #include #include +#include "utils.h" + int main(int argc, char **argv) { assert(argc == 2); const char *action = argv[1]; - fprintf(stderr, "%s:\n", action); + untag_fprintf(stderr, "%s:\n", action); static const size_t kMaxAllowedMallocSizePlusOne = (2UL << 30) + 1; void *x = nullptr; - if (!strcmp(action, "malloc")) { + if (!untag_strcmp(action, "malloc")) { x = malloc(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "calloc")) { + } else if (!untag_strcmp(action, "calloc")) { x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4); - } else if (!strcmp(action, "calloc-overflow")) { + } else if (!untag_strcmp(action, "calloc-overflow")) { volatile size_t kMaxSizeT = std::numeric_limits::max(); size_t kArraySize = 4096; volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10; x = calloc(kArraySize, kArraySize2); - } else if (!strcmp(action, "realloc")) { + } else if (!untag_strcmp(action, "realloc")) { x = realloc(0, kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "realloc-after-malloc")) { + } else if (!untag_strcmp(action, "realloc-after-malloc")) { char *t = (char*)malloc(100); *t = 42; x = realloc(t, kMaxAllowedMallocSizePlusOne); assert(*t == 42); free(t); - } else if (!strcmp(action, "new")) { + } else if (!untag_strcmp(action, "new")) { x = operator new(kMaxAllowedMallocSizePlusOne); - } else if (!strcmp(action, "new-nothrow")) { + } else if (!untag_strcmp(action, "new-nothrow")) { x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow); } else { assert(0); } - fprintf(stderr, "errno: %d\n", errno); + untag_fprintf(stderr, "errno: %d\n", errno); free(x); Index: compiler-rt/trunk/test/hwasan/TestCases/heap-buffer-overflow.c =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/heap-buffer-overflow.c +++ compiler-rt/trunk/test/hwasan/TestCases/heap-buffer-overflow.c @@ -15,6 +15,8 @@ #include #include +#include "utils.h" + static volatile char sink; int main(int argc, char **argv) { @@ -22,7 +24,7 @@ int offset = argc < 2 ? 40 : atoi(argv[1]); int size = argc < 3 ? 30 : atoi(argv[2]); char * volatile x = (char*)malloc(size); - fprintf(stderr, "base: %p access: %p\n", x, &x[offset]); + untag_fprintf(stderr, "base: %p access: %p\n", x, &x[offset]); sink = x[offset]; // CHECK40: allocated heap chunk; size: 32 offset: 8 Index: compiler-rt/trunk/test/hwasan/TestCases/malloc_fill.cpp =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/malloc_fill.cpp +++ compiler-rt/trunk/test/hwasan/TestCases/malloc_fill.cpp @@ -5,15 +5,18 @@ // RUN: %env_hwasan_opts=max_malloc_fill_size=20:malloc_fill_byte=171 %run %t | FileCheck %s --check-prefix=CHECK-20-ab #include + +#include "utils.h" + int main(int argc, char **argv) { // With asan allocator this makes sure we get memory from mmap. static const int kSize = 1 << 25; unsigned char *x = new unsigned char[kSize]; - printf("-"); + untag_printf("-"); for (int i = 0; i <= 32; i++) { - printf("%02x", x[i]); + untag_printf("%02x", x[i]); } - printf("-\n"); + untag_printf("-\n"); delete [] x; } Index: compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c +++ compiler-rt/trunk/test/hwasan/TestCases/many-threads-uaf.c @@ -7,6 +7,8 @@ #include +#include "utils.h" + void *BoringThread(void *arg) { char * volatile x = (char*)malloc(10); x[5] = 0; @@ -23,7 +25,7 @@ void *UAFThread(void *arg) { char * volatile x = (char*)malloc(10); - fprintf(stderr, "ZZZ %p\n", x); + untag_fprintf(stderr, "ZZZ %p\n", x); free(x); x[5] = 42; // CHECK: ERROR: HWAddressSanitizer: tag-mismatch on address Index: compiler-rt/trunk/test/hwasan/TestCases/mem-intrinsics.c =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/mem-intrinsics.c +++ compiler-rt/trunk/test/hwasan/TestCases/mem-intrinsics.c @@ -9,6 +9,8 @@ #include #include +#include "utils.h" + int main() { char Q[16] __attribute__((aligned(256))); char P[16] __attribute__((aligned(256))); @@ -19,7 +21,7 @@ #elif TEST_NO == 3 memcpy(Q, P, 32); #endif - write(STDOUT_FILENO, "recovered\n", 10); + write(STDOUT_FILENO, UNTAG("recovered\n"), 10); // WRITE: ERROR: HWAddressSanitizer: tag-mismatch on address // WRITE: WRITE of size 32 at {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem) // WRITE: Invalid access starting at offset [16, 32) Index: compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp +++ compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp @@ -34,9 +34,11 @@ #include #include +#include "utils.h" + int main(int argc, char **argv) { assert(argc <= 3); - bool test_size_max = argc == 3 && !strcmp(argv[2], "max"); + bool test_size_max = argc == 3 && !untag_strcmp(argv[2], "max"); static const size_t kMaxAllowedMallocSize = 1ULL << 40; static const size_t kChunkHeaderSize = 16; @@ -44,28 +46,28 @@ size_t MallocSize = test_size_max ? std::numeric_limits::max() : kMaxAllowedMallocSize; - if (!strcmp(argv[1], "malloc")) { + if (!untag_strcmp(argv[1], "malloc")) { void *p = malloc(MallocSize); assert(!p); p = malloc(kMaxAllowedMallocSize - kChunkHeaderSize); assert(!p); - } else if (!strcmp(argv[1], "calloc")) { + } else if (!untag_strcmp(argv[1], "calloc")) { // Trigger an overflow in calloc. size_t size = std::numeric_limits::max(); void *p = calloc((size / 0x1000) + 1, 0x1000); assert(!p); - } else if (!strcmp(argv[1], "reallocarray")) { + } else if (!untag_strcmp(argv[1], "reallocarray")) { // Trigger an overflow in reallocarray. size_t size = std::numeric_limits::max(); void *p = __sanitizer_reallocarray(nullptr, (size / 0x1000) + 1, 0x1000); assert(!p); - } else if (!strcmp(argv[1], "new")) { + } else if (!untag_strcmp(argv[1], "new")) { void *p = operator new(MallocSize); assert(!p); - } else if (!strcmp(argv[1], "new-nothrow")) { + } else if (!untag_strcmp(argv[1], "new-nothrow")) { void *p = operator new(MallocSize, std::nothrow); assert(!p); - } else if (!strcmp(argv[1], "usable")) { + } else if (!untag_strcmp(argv[1], "usable")) { // Playing with the actual usable size of a chunk. void *p = malloc(1007); assert(p); Index: compiler-rt/trunk/test/hwasan/TestCases/tail-magic.c =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/tail-magic.c +++ compiler-rt/trunk/test/hwasan/TestCases/tail-magic.c @@ -10,20 +10,22 @@ #include #include +#include "utils.h" + static volatile char *sink; // Overwrite the tail in a non-hwasan function so that we don't detect the // stores as OOB. __attribute__((no_sanitize("hwaddress"))) void overwrite_tail() { - sink[20] = 0x42; - sink[24] = 0x66; + (*UNTAG(&sink))[20] = 0x42; + (*UNTAG(&sink))[24] = 0x66; } int main(int argc, char **argv) { __hwasan_enable_allocator_tagging(); char *p = (char*)malloc(20); - sink = (char *)((uintptr_t)(p) & 0xffffffffffffff); + sink = UNTAG(p); overwrite_tail(); free(p); // CHECK: ERROR: HWAddressSanitizer: alocation-tail-overwritten; heap object [{{.*}}) of size 20 Index: compiler-rt/trunk/test/hwasan/TestCases/use-after-free.c =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/use-after-free.c +++ compiler-rt/trunk/test/hwasan/TestCases/use-after-free.c @@ -11,12 +11,14 @@ #include #include +#include "utils.h" + int main() { __hwasan_enable_allocator_tagging(); char * volatile x = (char*)malloc(10); free(x); __hwasan_disable_allocator_tagging(); - fprintf(stderr, "Going to do a %s\n", ISREAD ? "READ" : "WRITE"); + untag_fprintf(stderr, ISREAD ? "Going to do a READ\n" : "Going to do a WRITE\n"); // CHECK: Going to do a [[TYPE:[A-Z]*]] int r = 0; if (ISREAD) r = x[5]; else x[5] = 42; // should be on the same line. Index: compiler-rt/trunk/test/hwasan/TestCases/utils.h =================================================================== --- compiler-rt/trunk/test/hwasan/TestCases/utils.h +++ compiler-rt/trunk/test/hwasan/TestCases/utils.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include +#include +#include + +#define UNTAG(x) (typeof((x) + 0))(((uintptr_t)(x)) & 0xffffffffffffff) + +__attribute__((no_sanitize("hwaddress"))) +int untag_printf(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int ret = vprintf(UNTAG(fmt), ap); + va_end(ap); + return ret; +} + +__attribute__((no_sanitize("hwaddress"))) +int untag_fprintf(FILE *stream, const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int ret = vfprintf(stream, UNTAG(fmt), ap); + va_end(ap); + return ret; +} + +int untag_strcmp(const char *s1, const char *s2) { + return strcmp(UNTAG(s1), UNTAG(s2)); +}