#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "components/gwp_asan/client/guarded_page_allocator.h"
#include <algorithm>
#include <bit>
#include <memory>
#include <random>
#include <utility>
#include "base/allocator/buildflags.h"
#include "base/bits.h"
#include "base/logging.h"
#include "base/memory/page_size.h"
#include "base/rand_util.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/lock.h"
#include "build/build_config.h"
#include "components/crash/core/common/crash_key.h"
#include "components/gwp_asan/client/gwp_asan.h"
#include "components/gwp_asan/client/thread_local_random_bit_generator.h"
#include "components/gwp_asan/common/allocation_info.h"
#include "components/gwp_asan/common/allocator_state.h"
#include "components/gwp_asan/common/crash_key_name.h"
#include "components/gwp_asan/common/pack_stack_trace.h"
#include "partition_alloc/buildflags.h"
#include "partition_alloc/gwp_asan_support.h"
#include "third_party/boringssl/src/include/openssl/rand.h"
#if BUILDFLAG(IS_ANDROID)
#include "components/crash/core/app/crashpad.h"
#endif
namespace gwp_asan {
namespace internal {
namespace {
template <typename T>
T RandomEviction(std::vector<T>* list) { … }
}
constexpr size_t GuardedPageAllocator::kOutOfMemoryCount;
constexpr size_t GuardedPageAllocator::kGpaAllocAlignment;
template <typename T>
void GuardedPageAllocator::SimpleFreeList<T>::Initialize(T max_entries) { … }
template <typename T>
void GuardedPageAllocator::SimpleFreeList<T>::Initialize(
T max_entries,
std::vector<T>&& free_list) { … }
template <typename T>
bool GuardedPageAllocator::SimpleFreeList<T>::Allocate(T* out,
const char* type) { … }
template <typename T>
void GuardedPageAllocator::SimpleFreeList<T>::Free(T entry) { … }
GuardedPageAllocator::PartitionAllocSlotFreeList::PartitionAllocSlotFreeList() =
default;
GuardedPageAllocator::PartitionAllocSlotFreeList::
~PartitionAllocSlotFreeList() = default;
void GuardedPageAllocator::PartitionAllocSlotFreeList::Initialize(
AllocatorState::SlotIdx max_entries) { … }
void GuardedPageAllocator::PartitionAllocSlotFreeList::Initialize(
AllocatorState::SlotIdx max_entries,
std::vector<AllocatorState::SlotIdx>&& free_list) { … }
bool GuardedPageAllocator::PartitionAllocSlotFreeList::Allocate(
AllocatorState::SlotIdx* out,
const char* type) { … }
void GuardedPageAllocator::PartitionAllocSlotFreeList::Free(
AllocatorState::SlotIdx entry) { … }
GuardedPageAllocator::GuardedPageAllocator() { … }
void GuardedPageAllocator::Init(const AllocatorSettings& settings,
OutOfMemoryCallback oom_callback,
bool is_partition_alloc) { … }
std::vector<std::pair<void*, size_t>>
GuardedPageAllocator::GetInternalMemoryRegions() { … }
#if BUILDFLAG(USE_PARTITION_ALLOC_AS_GWP_ASAN_STORE)
GuardedPageAllocator::~GuardedPageAllocator() = default;
#else
GuardedPageAllocator::~GuardedPageAllocator() {
if (state_.total_requested_pages)
UnmapRegion();
}
#endif
void* GuardedPageAllocator::MapRegionHint() const { … }
void* GuardedPageAllocator::Allocate(size_t size,
size_t align,
const char* type) { … }
void GuardedPageAllocator::Deallocate(void* ptr) { … }
size_t GuardedPageAllocator::GetRequestedSize(const void* ptr) const { … }
size_t GuardedPageAllocator::RegionSize() const { … }
bool GuardedPageAllocator::ReserveSlotAndMetadata(
AllocatorState::SlotIdx* slot,
AllocatorState::MetadataIdx* metadata_idx,
const char* type) { … }
void GuardedPageAllocator::FreeSlotAndMetadata(
AllocatorState::SlotIdx slot,
AllocatorState::MetadataIdx metadata_idx) { … }
void GuardedPageAllocator::RecordAllocationMetadata(
AllocatorState::MetadataIdx metadata_idx,
size_t size,
void* ptr) { … }
void GuardedPageAllocator::RecordDeallocationMetadata(
AllocatorState::MetadataIdx metadata_idx) { … }
std::string GuardedPageAllocator::GetCrashKey() const { … }
}
}