[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:
Ryan Macnak
2023-06-14 21:50:17 +00:00
committed by Commit Queue
parent 89ba8f6e7c
commit c7b288492a
4 changed files with 36 additions and 0 deletions
+5
View File
@@ -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)
+10
View File
@@ -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)
+16
View File
@@ -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
View File
@@ -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;
}
}