Commit b2f8280e authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[zone] Teach ASan about the zone segment pool

This adds proper poisoning/unpoisoning to segments put into the segment
pool of an accounting allocator, and also marks a segment uninitialized
when returning it from the pool. This gives ASan a better chance at
catching use-after-free and others.

Drive-by: Fix type check in ASAN_POISON_MEMORY_REGION

R=mstarzinger@chromium.org

Change-Id: Iadbdd7c0a0c80da8e7b9bb8f3399209715436073
Reviewed-on: https://chromium-review.googlesource.com/c/1489086
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59932}
parent 5ebb8527
......@@ -16,12 +16,10 @@
#else // !V8_USE_ADDRESS_SANITIZER
#define ASAN_POISON_MEMORY_REGION(start, size) \
static_assert( \
(std::is_pointer<decltype(start)>::value || \
std::is_same<v8::internal::Address, decltype(start)>::value) && \
std::is_convertible<decltype(size), size_t>::value, \
"static type violation")
#define ASAN_POISON_MEMORY_REGION(start, size) \
static_assert(std::is_pointer<decltype(start)>::value && \
std::is_convertible<decltype(size), size_t>::value, \
"static type violation")
#define ASAN_UNPOISON_MEMORY_REGION(start, size) \
ASAN_POISON_MEMORY_REGION(start, size)
......
......@@ -11,6 +11,8 @@
#endif
#include "src/allocation.h"
#include "src/asan.h"
#include "src/msan.h"
namespace v8 {
namespace internal {
......@@ -124,23 +126,24 @@ Segment* AccountingAllocator::GetSegmentFromPool(size_t requested_size) {
power -= kMinSegmentSizePower;
Segment* segment;
{
base::MutexGuard lock_guard(&unused_segments_mutex_);
segment = unused_segments_heads_[power];
if (segment == nullptr) return nullptr;
if (segment != nullptr) {
unused_segments_heads_[power] = segment->next();
segment->set_next(nullptr);
unused_segments_heads_[power] = segment->next();
segment->set_next(nullptr);
unused_segments_sizes_[power]--;
current_pool_size_.fetch_sub(segment->size(), std::memory_order_relaxed);
}
unused_segments_sizes_[power]--;
}
if (segment) {
DCHECK_GE(segment->size(), requested_size);
}
current_pool_size_.fetch_sub(segment->size(), std::memory_order_relaxed);
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<void*>(segment->start()),
segment->size());
MSAN_ALLOCATED_UNINITIALIZED_MEMORY(segment->start(), segment->size());
DCHECK_GE(segment->size(), requested_size);
return segment;
}
......@@ -167,10 +170,15 @@ bool AccountingAllocator::AddSegmentToPool(Segment* segment) {
segment->set_next(unused_segments_heads_[power]);
unused_segments_heads_[power] = segment;
current_pool_size_.fetch_add(size, std::memory_order_relaxed);
unused_segments_sizes_[power]++;
// Poisoning needs to happen while still holding the mutex to guarantee that
// it happens before the segment is taken from the pool again.
ASAN_POISON_MEMORY_REGION(reinterpret_cast<void*>(segment->start()),
segment->size());
}
current_pool_size_.fetch_add(size, std::memory_order_relaxed);
return true;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment