blob: 2ab3b6b50c3421e11b402be483a2fe21842feca4 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <windows.h>
#include "components/gwp_asan/client/guarded_page_allocator.h"
#include "base/logging.h"
#include "build/build_config.h"
namespace gwp_asan {
namespace internal {
// TODO(vtsyrklevich): See if the platform-specific memory allocation and
// protection routines can be broken out in base/ and merged with those used for
// PartionAlloc/ProtectedMemory.
bool GuardedPageAllocator::MapPages() {
size_t len = (2 * state_.num_pages + 1) * state_.page_size;
void* base_ptr = VirtualAlloc(nullptr, len, MEM_RESERVE, PAGE_NOACCESS);
if (!base_ptr) {
DPLOG(ERROR) << "Failed to reserve guarded allocator region";
return false;
}
uintptr_t base_addr = reinterpret_cast<uintptr_t>(base_ptr);
// Commit the pages used for allocations.
for (size_t i = 0; i < state_.num_pages; i++) {
uintptr_t address = base_addr + state_.page_size * ((2 * i) + 1);
LPVOID ret = VirtualAlloc(reinterpret_cast<LPVOID>(address),
state_.page_size, MEM_COMMIT, PAGE_NOACCESS);
if (!ret) {
PLOG(ERROR) << "Failed to commit allocation page";
UnmapPages();
return false;
}
}
state_.pages_base_addr = base_addr;
state_.first_page_addr = state_.pages_base_addr + state_.page_size;
state_.pages_end_addr = state_.pages_base_addr + len;
return true;
}
void GuardedPageAllocator::UnmapPages() {
DCHECK(state_.pages_base_addr);
BOOL err = VirtualFree(reinterpret_cast<void*>(state_.pages_base_addr), 0,
MEM_RELEASE);
DCHECK(err);
(void)err;
}
void GuardedPageAllocator::MarkPageReadWrite(void* ptr) {
DWORD old_prot;
BOOL err = VirtualProtect(ptr, state_.page_size, PAGE_READWRITE, &old_prot);
PCHECK(err != 0) << "VirtualProtect";
}
void GuardedPageAllocator::MarkPageInaccessible(void* ptr) {
DWORD old_prot;
BOOL err = VirtualProtect(ptr, state_.page_size, PAGE_NOACCESS, &old_prot);
PCHECK(err != 0) << "VirtualProtect";
}
} // namespace internal
} // namespace gwp_asan