summaryrefslogtreecommitdiff
path: root/libsanitizer/asan
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2019-11-07 10:33:54 +0100
committerMartin Liska <marxin@gcc.gnu.org>2019-11-07 09:33:54 +0000
commitcb7dc4da4ccc475675b5aec6a08d3e8c0a1761e4 (patch)
tree610840af295a13e6f4c2e87e7bfe52a4723ca534 /libsanitizer/asan
parent29f3def30844dd13e79972fa03a50af68120f7ac (diff)
Libsanitizer: merge from trunk
2019-11-07 Martin Liska <mliska@suse.cz> * merge.sh: Update to use llvm-project git repository. * all source files: Merge from upstream 82588e05cc32bb30807e480abd4e689b0dee132a. From-SVN: r277909
Diffstat (limited to 'libsanitizer/asan')
-rw-r--r--libsanitizer/asan/asan_allocator.cpp28
-rw-r--r--libsanitizer/asan/asan_globals.cpp19
-rw-r--r--libsanitizer/asan/asan_interceptors.h7
-rw-r--r--libsanitizer/asan/asan_interface.inc1
-rw-r--r--libsanitizer/asan/asan_interface_internal.h3
-rw-r--r--libsanitizer/asan/asan_malloc_win.cpp3
-rw-r--r--libsanitizer/asan/asan_mapping.h2
7 files changed, 50 insertions, 13 deletions
diff --git a/libsanitizer/asan/asan_allocator.cpp b/libsanitizer/asan/asan_allocator.cpp
index c9e9f5a93d0..65c51fbafdd 100644
--- a/libsanitizer/asan/asan_allocator.cpp
+++ b/libsanitizer/asan/asan_allocator.cpp
@@ -246,6 +246,7 @@ struct Allocator {
AllocatorCache fallback_allocator_cache;
QuarantineCache fallback_quarantine_cache;
+ uptr max_user_defined_malloc_size;
atomic_uint8_t rss_limit_exceeded;
// ------------------- Options --------------------------
@@ -280,6 +281,10 @@ struct Allocator {
SetAllocatorMayReturnNull(options.may_return_null);
allocator.InitLinkerInitialized(options.release_to_os_interval_ms);
SharedInitCode(options);
+ max_user_defined_malloc_size = common_flags()->max_allocation_size_mb
+ ? common_flags()->max_allocation_size_mb
+ << 20
+ : kMaxAllowedMallocSize;
}
bool RssLimitExceeded() {
@@ -394,6 +399,16 @@ struct Allocator {
return right_chunk;
}
+ bool UpdateAllocationStack(uptr addr, BufferedStackTrace *stack) {
+ AsanChunk *m = GetAsanChunkByAddr(addr);
+ if (!m) return false;
+ if (m->chunk_state != CHUNK_ALLOCATED) return false;
+ if (m->Beg() != addr) return false;
+ atomic_store((atomic_uint32_t *)&m->alloc_context_id, StackDepotPut(*stack),
+ memory_order_relaxed);
+ return true;
+ }
+
// -------------------- Allocation/Deallocation routines ---------------
void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack,
AllocType alloc_type, bool can_fill) {
@@ -435,14 +450,16 @@ struct Allocator {
using_primary_allocator = false;
}
CHECK(IsAligned(needed_size, min_alignment));
- if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) {
+ if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize ||
+ size > max_user_defined_malloc_size) {
if (AllocatorMayReturnNull()) {
Report("WARNING: AddressSanitizer failed to allocate 0x%zx bytes\n",
(void*)size);
return nullptr;
}
- ReportAllocationSizeTooBig(size, needed_size, kMaxAllowedMallocSize,
- stack);
+ uptr malloc_limit =
+ Min(kMaxAllowedMallocSize, max_user_defined_malloc_size);
+ ReportAllocationSizeTooBig(size, needed_size, malloc_limit, stack);
}
AsanThread *t = GetCurrentThread();
@@ -1105,6 +1122,11 @@ void __sanitizer_purge_allocator() {
instance.Purge(&stack);
}
+int __asan_update_allocation_context(void* addr) {
+ GET_STACK_TRACE_MALLOC;
+ return instance.UpdateAllocationStack((uptr)addr, &stack);
+}
+
#if !SANITIZER_SUPPORTS_WEAK_HOOKS
// Provide default (no-op) implementation of malloc hooks.
SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook,
diff --git a/libsanitizer/asan/asan_globals.cpp b/libsanitizer/asan/asan_globals.cpp
index e045c31cd1c..9d7dbc6f264 100644
--- a/libsanitizer/asan/asan_globals.cpp
+++ b/libsanitizer/asan/asan_globals.cpp
@@ -154,6 +154,23 @@ static void CheckODRViolationViaIndicator(const Global *g) {
}
}
+// Check ODR violation for given global G by checking if it's already poisoned.
+// We use this method in case compiler doesn't use private aliases for global
+// variables.
+static void CheckODRViolationViaPoisoning(const Global *g) {
+ if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
+ // This check may not be enough: if the first global is much larger
+ // the entire redzone of the second global may be within the first global.
+ for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
+ if (g->beg == l->g->beg &&
+ (flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
+ !IsODRViolationSuppressed(g->name))
+ ReportODRViolation(g, FindRegistrationSite(g),
+ l->g, FindRegistrationSite(l->g));
+ }
+ }
+}
+
// Clang provides two different ways for global variables protection:
// it can poison the global itself or its private alias. In former
// case we may poison same symbol multiple times, that can help us to
@@ -199,6 +216,8 @@ static void RegisterGlobal(const Global *g) {
// where two globals with the same name are defined in different modules.
if (UseODRIndicator(g))
CheckODRViolationViaIndicator(g);
+ else
+ CheckODRViolationViaPoisoning(g);
}
if (CanPoisonMemory())
PoisonRedZones(*g);
diff --git a/libsanitizer/asan/asan_interceptors.h b/libsanitizer/asan/asan_interceptors.h
index b7a85fedbdf..344a64bd83d 100644
--- a/libsanitizer/asan/asan_interceptors.h
+++ b/libsanitizer/asan/asan_interceptors.h
@@ -80,12 +80,7 @@ void InitializePlatformInterceptors();
#if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \
!SANITIZER_NETBSD
# define ASAN_INTERCEPT___CXA_THROW 1
-# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \
- || ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION
-# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
-# else
-# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0
-# endif
+# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
# if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__))
# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1
# else
diff --git a/libsanitizer/asan/asan_interface.inc b/libsanitizer/asan/asan_interface.inc
index 7c341f22e15..94801043982 100644
--- a/libsanitizer/asan/asan_interface.inc
+++ b/libsanitizer/asan/asan_interface.inc
@@ -164,6 +164,7 @@ INTERFACE_FUNCTION(__sanitizer_unaligned_load64)
INTERFACE_FUNCTION(__sanitizer_unaligned_store16)
INTERFACE_FUNCTION(__sanitizer_unaligned_store32)
INTERFACE_FUNCTION(__sanitizer_unaligned_store64)
+INTERFACE_FUNCTION(__asan_update_allocation_context)
INTERFACE_WEAK_FUNCTION(__asan_default_options)
INTERFACE_WEAK_FUNCTION(__asan_default_suppressions)
INTERFACE_WEAK_FUNCTION(__asan_on_error)
diff --git a/libsanitizer/asan/asan_interface_internal.h b/libsanitizer/asan/asan_interface_internal.h
index c83aa11d741..f14cbbcb76a 100644
--- a/libsanitizer/asan/asan_interface_internal.h
+++ b/libsanitizer/asan/asan_interface_internal.h
@@ -251,6 +251,9 @@ extern "C" {
const char* __asan_default_suppressions();
SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_vfork(void *sp);
+
+ SANITIZER_INTERFACE_ATTRIBUTE int __asan_update_allocation_context(
+ void *addr);
} // extern "C"
#endif // ASAN_INTERFACE_INTERNAL_H
diff --git a/libsanitizer/asan/asan_malloc_win.cpp b/libsanitizer/asan/asan_malloc_win.cpp
index 13c6f652119..4b76d4ebd3e 100644
--- a/libsanitizer/asan/asan_malloc_win.cpp
+++ b/libsanitizer/asan/asan_malloc_win.cpp
@@ -35,11 +35,8 @@ constexpr unsigned long HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
constexpr unsigned long HEAP_ALLOCATE_SUPPORTED_FLAGS = (HEAP_ZERO_MEMORY);
constexpr unsigned long HEAP_ALLOCATE_UNSUPPORTED_FLAGS =
(~HEAP_ALLOCATE_SUPPORTED_FLAGS);
-constexpr unsigned long HEAP_FREE_SUPPORTED_FLAGS = (0);
constexpr unsigned long HEAP_FREE_UNSUPPORTED_FLAGS =
(~HEAP_ALLOCATE_SUPPORTED_FLAGS);
-constexpr unsigned long HEAP_REALLOC_SUPPORTED_FLAGS =
- (HEAP_REALLOC_IN_PLACE_ONLY | HEAP_ZERO_MEMORY);
constexpr unsigned long HEAP_REALLOC_UNSUPPORTED_FLAGS =
(~HEAP_ALLOCATE_SUPPORTED_FLAGS);
diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h
index 09be904270c..41fb49ee46d 100644
--- a/libsanitizer/asan/asan_mapping.h
+++ b/libsanitizer/asan/asan_mapping.h
@@ -163,7 +163,7 @@ static const u64 kDefaultShort64bitShadowOffset =
static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
-static const u64 kPPC64_ShadowOffset64 = 1ULL << 41;
+static const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000
static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000