summaryrefslogtreecommitdiffstats
path: root/compiler-rt
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2014-12-17 00:01:02 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2014-12-17 00:01:02 +0000
commit91bb25f515268aa52c8f2d08fdcd2f08d617585b (patch)
tree80091fe77acf8dbbb5930175cecd67ec9dc5777c /compiler-rt
parent0317bc9e55c9e4546416e8d141d4bca813adb67f (diff)
downloadbcm5719-llvm-91bb25f515268aa52c8f2d08fdcd2f08d617585b.tar.gz
bcm5719-llvm-91bb25f515268aa52c8f2d08fdcd2f08d617585b.zip
[ASan] Introduce SetCanPoisonMemory() function.
SetCanPoisonMemory()/CanPoisonMemory() functions are now used instead of "poison_heap" flag to determine if ASan is allowed to poison the shadow memory. This allows to hot-patch this value in runtime (e.g. during ASan activation) without introducing a data race. llvm-svn: 224395
Diffstat (limited to 'compiler-rt')
-rw-r--r--compiler-rt/lib/asan/asan_activation.cc6
-rw-r--r--compiler-rt/lib/asan/asan_allocator2.cc6
-rw-r--r--compiler-rt/lib/asan/asan_globals.cc8
-rw-r--r--compiler-rt/lib/asan/asan_poisoning.cc15
-rw-r--r--compiler-rt/lib/asan/asan_poisoning.h8
-rw-r--r--compiler-rt/lib/asan/asan_rtl.cc1
6 files changed, 31 insertions, 13 deletions
diff --git a/compiler-rt/lib/asan/asan_activation.cc b/compiler-rt/lib/asan/asan_activation.cc
index 02e09119271..8776f53fa4e 100644
--- a/compiler-rt/lib/asan/asan_activation.cc
+++ b/compiler-rt/lib/asan/asan_activation.cc
@@ -16,6 +16,7 @@
#include "asan_allocator.h"
#include "asan_flags.h"
#include "asan_internal.h"
+#include "asan_poisoning.h"
#include "asan_stack.h"
#include "sanitizer_common/sanitizer_flags.h"
@@ -62,12 +63,12 @@ void AsanActivate() {
// Restore flag values.
// FIXME: this is not atomic, and there may be other threads alive.
flags()->max_redzone = asan_deactivated_flags.max_redzone;
- flags()->poison_heap = asan_deactivated_flags.poison_heap;
flags()->alloc_dealloc_mismatch =
asan_deactivated_flags.alloc_dealloc_mismatch;
ParseExtraActivationFlags();
+ SetCanPoisonMemory(asan_deactivated_flags.poison_heap);
SetMallocContextSize(asan_deactivated_flags.malloc_context_size);
ReInitializeAllocator(asan_deactivated_flags.allocator_may_return_null,
asan_deactivated_flags.quarantine_size);
@@ -77,7 +78,8 @@ void AsanActivate() {
"malloc_context_size %d, alloc_dealloc_mismatch %d, "
"allocator_may_return_null %d\n",
asan_deactivated_flags.quarantine_size, flags()->max_redzone,
- flags()->poison_heap, asan_deactivated_flags.malloc_context_size,
+ asan_deactivated_flags.poison_heap,
+ asan_deactivated_flags.malloc_context_size,
flags()->alloc_dealloc_mismatch,
asan_deactivated_flags.allocator_may_return_null);
}
diff --git a/compiler-rt/lib/asan/asan_allocator2.cc b/compiler-rt/lib/asan/asan_allocator2.cc
index 8900c9746bc..a3ef524e100 100644
--- a/compiler-rt/lib/asan/asan_allocator2.cc
+++ b/compiler-rt/lib/asan/asan_allocator2.cc
@@ -312,9 +312,9 @@ static void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack,
allocated = allocator.Allocate(cache, needed_size, 8, false);
}
- if (*(u8 *)MEM_TO_SHADOW((uptr)allocated) == 0 && flags()->poison_heap) {
+ if (*(u8 *)MEM_TO_SHADOW((uptr)allocated) == 0 && CanPoisonMemory()) {
// Heap poisoning is enabled, but the allocator provides an unpoisoned
- // chunk. This is possible if flags()->poison_heap was disabled for some
+ // chunk. This is possible if CanPoisonMemory() was false for some
// time, for example, due to flags()->start_disabled.
// Anyway, poison the block before using it for anything else.
uptr allocated_size = allocator.GetActuallyAllocatedSize(allocated);
@@ -362,7 +362,7 @@ static void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack,
if (size_rounded_down_to_granularity)
PoisonShadow(user_beg, size_rounded_down_to_granularity, 0);
// Deal with the end of the region if size is not aligned to granularity.
- if (size != size_rounded_down_to_granularity && fl.poison_heap) {
+ if (size != size_rounded_down_to_granularity && CanPoisonMemory()) {
u8 *shadow = (u8*)MemToShadow(user_beg + size_rounded_down_to_granularity);
*shadow = fl.poison_partial ? (size & (SHADOW_GRANULARITY - 1)) : 0;
}
diff --git a/compiler-rt/lib/asan/asan_globals.cc b/compiler-rt/lib/asan/asan_globals.cc
index be111d4fb4c..c4571953c40 100644
--- a/compiler-rt/lib/asan/asan_globals.cc
+++ b/compiler-rt/lib/asan/asan_globals.cc
@@ -164,7 +164,7 @@ static void RegisterGlobal(const Global *g) {
}
}
}
- if (flags()->poison_heap)
+ if (CanPoisonMemory())
PoisonRedZones(*g);
ListOfGlobals *l = new(allocator_for_globals) ListOfGlobals;
l->g = g;
@@ -186,7 +186,7 @@ static void UnregisterGlobal(const Global *g) {
CHECK(AddrIsInMem(g->beg));
CHECK(AddrIsAlignedByGranularity(g->beg));
CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
- if (flags()->poison_heap)
+ if (CanPoisonMemory())
PoisonShadowForGlobal(g, 0);
// We unpoison the shadow memory for the global but we do not remove it from
// the list because that would require O(n^2) time with the current list
@@ -249,7 +249,7 @@ void __asan_unregister_globals(__asan_global *globals, uptr n) {
// initializer can only touch global variables in the same TU.
void __asan_before_dynamic_init(const char *module_name) {
if (!flags()->check_initialization_order ||
- !flags()->poison_heap)
+ !CanPoisonMemory())
return;
bool strict_init_order = flags()->strict_init_order;
CHECK(dynamic_init_globals);
@@ -275,7 +275,7 @@ void __asan_before_dynamic_init(const char *module_name) {
// TU are poisoned. It simply unpoisons all dynamically initialized globals.
void __asan_after_dynamic_init() {
if (!flags()->check_initialization_order ||
- !flags()->poison_heap)
+ !CanPoisonMemory())
return;
CHECK(asan_inited);
BlockingMutexLock lock(&mu_for_globals);
diff --git a/compiler-rt/lib/asan/asan_poisoning.cc b/compiler-rt/lib/asan/asan_poisoning.cc
index 1c6e92f69c6..11fa271b238 100644
--- a/compiler-rt/lib/asan/asan_poisoning.cc
+++ b/compiler-rt/lib/asan/asan_poisoning.cc
@@ -15,13 +15,24 @@
#include "asan_poisoning.h"
#include "asan_report.h"
#include "asan_stack.h"
+#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_flags.h"
namespace __asan {
+static atomic_uint8_t can_poison_memory;
+
+void SetCanPoisonMemory(bool value) {
+ atomic_store(&can_poison_memory, value, memory_order_release);
+}
+
+bool CanPoisonMemory() {
+ return atomic_load(&can_poison_memory, memory_order_acquire);
+}
+
void PoisonShadow(uptr addr, uptr size, u8 value) {
- if (!flags()->poison_heap) return;
+ if (!CanPoisonMemory()) return;
CHECK(AddrIsAlignedByGranularity(addr));
CHECK(AddrIsInMem(addr));
CHECK(AddrIsAlignedByGranularity(addr + size));
@@ -34,7 +45,7 @@ void PoisonShadowPartialRightRedzone(uptr addr,
uptr size,
uptr redzone_size,
u8 value) {
- if (!flags()->poison_heap) return;
+ if (!CanPoisonMemory()) return;
CHECK(AddrIsAlignedByGranularity(addr));
CHECK(AddrIsInMem(addr));
FastPoisonShadowPartialRightRedzone(addr, size, redzone_size, value);
diff --git a/compiler-rt/lib/asan/asan_poisoning.h b/compiler-rt/lib/asan/asan_poisoning.h
index feda1a98454..73ae12fbc46 100644
--- a/compiler-rt/lib/asan/asan_poisoning.h
+++ b/compiler-rt/lib/asan/asan_poisoning.h
@@ -19,6 +19,10 @@
namespace __asan {
+// Enable/disable memory poisoning.
+void SetCanPoisonMemory(bool value);
+bool CanPoisonMemory();
+
// Poisons the shadow memory for "size" bytes starting from "addr".
void PoisonShadow(uptr addr, uptr size, u8 value);
@@ -34,7 +38,7 @@ void PoisonShadowPartialRightRedzone(uptr addr,
// performance-critical code with care.
ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
u8 value) {
- DCHECK(flags()->poison_heap);
+ DCHECK(CanPoisonMemory());
uptr shadow_beg = MEM_TO_SHADOW(aligned_beg);
uptr shadow_end = MEM_TO_SHADOW(
aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1;
@@ -68,7 +72,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone(
uptr aligned_addr, uptr size, uptr redzone_size, u8 value) {
- DCHECK(flags()->poison_heap);
+ DCHECK(CanPoisonMemory());
bool poison_partial = flags()->poison_partial;
u8 *shadow = (u8*)MEM_TO_SHADOW(aligned_addr);
for (uptr i = 0; i < redzone_size; i += SHADOW_GRANULARITY, shadow++) {
diff --git a/compiler-rt/lib/asan/asan_rtl.cc b/compiler-rt/lib/asan/asan_rtl.cc
index 6cd018b3a71..e6d18355ed3 100644
--- a/compiler-rt/lib/asan/asan_rtl.cc
+++ b/compiler-rt/lib/asan/asan_rtl.cc
@@ -570,6 +570,7 @@ static void AsanInitInternal() {
const char *options = GetEnv("ASAN_OPTIONS");
InitializeFlags(flags(), options);
+ SetCanPoisonMemory(flags()->poison_heap);
SetMallocContextSize(common_flags()->malloc_context_size);
InitializeHighMemEnd();
OpenPOWER on IntegriCloud