diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2019-02-15 18:38:03 +0000 |
---|---|---|
committer | Evgenii Stepanov <eugenis@google.com> | 2019-03-20 12:53:44 -0700 |
commit | e47d9957464911baad943fc951c1120e84c9d2e5 (patch) | |
tree | 3c84802708b598f9f7bfc089df84cb6058ecdb97 | |
parent | 121e859b09d8f0e17c1570de04d845855d1658c9 (diff) | |
download | compiler-rt-e47d9957464911baad943fc951c1120e84c9d2e5.tar.gz |
Fix false positive when tag_in_malloc=0,tag_in_free=1.
Summary:
With tag_in_free=1, malloc() can not assume that the memory is untagged,
and needs to retag is to 0.
Reviewers: pcc, kcc
Subscribers: kubamracek, jfb, jdoerfert, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D58158
Change-Id: I8e09206f2d1d9041457943ad8a3cd638cfbb8778
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@354155 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/hwasan/hwasan_allocator.cc | 14 | ||||
-rw-r--r-- | test/hwasan/TestCases/tag_in_free.c | 51 |
2 files changed, 61 insertions, 4 deletions
diff --git a/lib/hwasan/hwasan_allocator.cc b/lib/hwasan/hwasan_allocator.cc index dc56bd7ef..4a4de3e45 100644 --- a/lib/hwasan/hwasan_allocator.cc +++ b/lib/hwasan/hwasan_allocator.cc @@ -176,10 +176,16 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, size - orig_size); void *user_ptr = allocated; - if (flags()->tag_in_malloc && - atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) - user_ptr = (void *)TagMemoryAligned( - (uptr)user_ptr, size, t ? t->GenerateRandomTag() : kFallbackAllocTag); + // Tagging can only be skipped when both tag_in_malloc and tag_in_free are + // false. When tag_in_malloc = false and tag_in_free = true malloc needs to + // retag to 0. + if ((flags()->tag_in_malloc || flags()->tag_in_free) && + atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) { + tag_t tag = flags()->tag_in_malloc + ? (t ? t->GenerateRandomTag() : kFallbackAllocTag) + : 0; + user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, size, tag); + } if ((orig_size % kShadowAlignment) && (alignment <= kShadowAlignment) && right_align_mode) { 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; +} |