[vm] Mark Zone memory as unallocated/allocated/uninitialized for Address and Memory Sanitizer.
TEST=ci Change-Id: Ia283d9aefec767e6ccc4f1c88abba73ce1c35e87 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/212022 Reviewed-by: Brian Quinlan <bquinlan@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
Commit Queue
parent
89ba8f6e7c
commit
c7b288492a
@@ -16,11 +16,16 @@
|
||||
#endif
|
||||
|
||||
#if defined(USING_ADDRESS_SANITIZER)
|
||||
extern "C" void __asan_poison_memory_region(void const volatile*, size_t);
|
||||
extern "C" void __asan_unpoison_memory_region(void const volatile*, size_t);
|
||||
#define NO_SANITIZE_ADDRESS __attribute__((no_sanitize("address")))
|
||||
#define ASAN_POISON(ptr, len) __asan_poison_memory_region(ptr, len)
|
||||
#define ASAN_UNPOISON(ptr, len) __asan_unpoison_memory_region(ptr, len)
|
||||
#else // defined(USING_ADDRESS_SANITIZER)
|
||||
#define NO_SANITIZE_ADDRESS
|
||||
#define ASAN_POISON(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == nullptr && (len) == 0)
|
||||
#define ASAN_UNPOISON(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == nullptr && (len) == 0)
|
||||
|
||||
@@ -19,9 +19,13 @@
|
||||
extern "C" void __msan_poison(const volatile void*, size_t);
|
||||
extern "C" void __msan_unpoison(const volatile void*, size_t);
|
||||
extern "C" void __msan_unpoison_param(size_t);
|
||||
extern "C" void __msan_allocated_memory(const volatile void*, size_t);
|
||||
extern "C" void __sanitizer_dtor_callback(const volatile void*, size_t);
|
||||
extern "C" void __msan_check_mem_is_initialized(const volatile void*, size_t);
|
||||
#define MSAN_POISON(ptr, len) __msan_poison(ptr, len)
|
||||
#define MSAN_UNPOISON(ptr, len) __msan_unpoison(ptr, len)
|
||||
#define MSAN_ALLOCATED(ptr, len) __msan_allocated_memory(ptr, len)
|
||||
#define MSAN_RELEASED(ptr, len) __sanitizer_dtor_callback(ptr, len)
|
||||
#define MSAN_CHECK_INITIALIZED(ptr, len) \
|
||||
__msan_check_mem_is_initialized(ptr, len)
|
||||
#define NO_SANITIZE_MEMORY __attribute__((no_sanitize("memory")))
|
||||
@@ -32,6 +36,12 @@ extern "C" void __msan_check_mem_is_initialized(const volatile void*, size_t);
|
||||
#define MSAN_UNPOISON(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == nullptr && (len) == 0)
|
||||
#define MSAN_ALLOCATED(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == nullptr && (len) == 0)
|
||||
#define MSAN_RELEASED(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == nullptr && (len) == 0)
|
||||
#define MSAN_CHECK_INITIALIZED(ptr, len) \
|
||||
do { \
|
||||
} while (false && (ptr) == nullptr && (len) == 0)
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
|
||||
#include "vm/zone.h"
|
||||
|
||||
#include "platform/address_sanitizer.h"
|
||||
#include "platform/assert.h"
|
||||
#include "platform/leak_sanitizer.h"
|
||||
#include "platform/memory_sanitizer.h"
|
||||
#include "platform/utils.h"
|
||||
#include "vm/dart_api_state.h"
|
||||
#include "vm/flags.h"
|
||||
@@ -96,10 +98,15 @@ Zone::Segment* Zone::Segment::New(intptr_t size, Zone::Segment* next) {
|
||||
OUT_OF_MEMORY();
|
||||
}
|
||||
Segment* result = reinterpret_cast<Segment*>(memory->start());
|
||||
|
||||
#ifdef DEBUG
|
||||
// Zap the entire allocated segment (including the header).
|
||||
memset(reinterpret_cast<void*>(result), kZapUninitializedByte, size);
|
||||
#endif
|
||||
ASAN_POISON(reinterpret_cast<void*>(result), size);
|
||||
MSAN_ALLOCATED(reinterpret_cast<void*>(result), size);
|
||||
|
||||
ASAN_UNPOISON(reinterpret_cast<void*>(result), sizeof(Segment));
|
||||
result->next_ = next;
|
||||
result->size_ = size;
|
||||
result->memory_ = memory;
|
||||
@@ -120,6 +127,9 @@ void Zone::Segment::DeleteSegmentList(Segment* head) {
|
||||
// Zap the entire current segment (including the header).
|
||||
memset(reinterpret_cast<void*>(current), kZapDeletedByte, current->size());
|
||||
#endif
|
||||
ASAN_POISON(reinterpret_cast<void*>(current), size);
|
||||
MSAN_RELEASED(reinterpret_cast<void*>(current), size);
|
||||
|
||||
LSAN_UNREGISTER_ROOT_REGION(current, sizeof(*current));
|
||||
|
||||
if (size == kSegmentSize) {
|
||||
@@ -133,6 +143,7 @@ void Zone::Segment::DeleteSegmentList(Segment* head) {
|
||||
}
|
||||
if (memory != nullptr) {
|
||||
total_size_.fetch_sub(size);
|
||||
ASAN_UNPOISON(reinterpret_cast<void*>(current), size);
|
||||
delete memory;
|
||||
}
|
||||
current = next;
|
||||
@@ -150,6 +161,8 @@ Zone::Zone()
|
||||
// Zap the entire initial buffer.
|
||||
memset(&buffer_, kZapUninitializedByte, kInitialChunkSize);
|
||||
#endif
|
||||
ASAN_POISON(&buffer_, kInitialChunkSize);
|
||||
MSAN_POISON(&buffer_, kInitialChunkSize);
|
||||
}
|
||||
|
||||
Zone::~Zone() {
|
||||
@@ -168,6 +181,9 @@ void Zone::Reset() {
|
||||
#ifdef DEBUG
|
||||
memset(&buffer_, kZapDeletedByte, kInitialChunkSize);
|
||||
#endif
|
||||
ASAN_POISON(&buffer_, kInitialChunkSize);
|
||||
MSAN_POISON(&buffer_, kInitialChunkSize);
|
||||
|
||||
position_ = reinterpret_cast<uword>(&buffer_);
|
||||
limit_ = position_ + kInitialChunkSize;
|
||||
size_ = 0;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#ifndef RUNTIME_VM_ZONE_H_
|
||||
#define RUNTIME_VM_ZONE_H_
|
||||
|
||||
#include "platform/address_sanitizer.h"
|
||||
#include "platform/utils.h"
|
||||
#include "vm/allocation.h"
|
||||
#include "vm/handles.h"
|
||||
@@ -277,6 +278,8 @@ inline uword Zone::AllocUnsafe(intptr_t size) {
|
||||
|
||||
// Check that the result has the proper alignment and return it.
|
||||
ASSERT(Utils::IsAligned(result, kAlignment));
|
||||
|
||||
ASAN_UNPOISON(reinterpret_cast<void*>(result), size);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -312,6 +315,8 @@ inline ElementType* Zone::Realloc(ElementType* old_data,
|
||||
if (new_end <= limit_) {
|
||||
position_ = Utils::RoundUp(new_end, kAlignment);
|
||||
size_ += static_cast<intptr_t>(new_len - old_len);
|
||||
ASAN_UNPOISON(reinterpret_cast<void*>(old_data),
|
||||
new_len * kElementSize);
|
||||
return old_data;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user