86 lines
2.5 KiB
C++
86 lines
2.5 KiB
C++
|
// Copyright (c) 2013 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 "base/process/memory.h"
|
||
|
|
||
|
#include <psapi.h>
|
||
|
|
||
|
#include "base/logging.h"
|
||
|
#include "base/memory/scoped_ptr.h"
|
||
|
|
||
|
namespace base {
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
void OnNoMemory() {
|
||
|
// Kill the process. This is important for security, since WebKit doesn't
|
||
|
// NULL-check many memory allocations. If a malloc fails, returns NULL, and
|
||
|
// the buffer is then used, it provides a handy mapping of memory starting at
|
||
|
// address 0 for an attacker to utilize.
|
||
|
__debugbreak();
|
||
|
_exit(1);
|
||
|
}
|
||
|
|
||
|
// HeapSetInformation function pointer.
|
||
|
typedef BOOL (WINAPI* HeapSetFn)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T);
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
bool EnableLowFragmentationHeap() {
|
||
|
HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
|
||
|
HeapSetFn heap_set = reinterpret_cast<HeapSetFn>(GetProcAddress(
|
||
|
kernel32,
|
||
|
"HeapSetInformation"));
|
||
|
|
||
|
// On Windows 2000, the function is not exported. This is not a reason to
|
||
|
// fail.
|
||
|
if (!heap_set)
|
||
|
return true;
|
||
|
|
||
|
unsigned number_heaps = GetProcessHeaps(0, NULL);
|
||
|
if (!number_heaps)
|
||
|
return false;
|
||
|
|
||
|
// Gives us some extra space in the array in case a thread is creating heaps
|
||
|
// at the same time we're querying them.
|
||
|
static const int MARGIN = 8;
|
||
|
scoped_ptr<HANDLE[]> heaps(new HANDLE[number_heaps + MARGIN]);
|
||
|
number_heaps = GetProcessHeaps(number_heaps + MARGIN, heaps.get());
|
||
|
if (!number_heaps)
|
||
|
return false;
|
||
|
|
||
|
for (unsigned i = 0; i < number_heaps; ++i) {
|
||
|
ULONG lfh_flag = 2;
|
||
|
// Don't bother with the result code. It may fails on heaps that have the
|
||
|
// HEAP_NO_SERIALIZE flag. This is expected and not a problem at all.
|
||
|
heap_set(heaps[i],
|
||
|
HeapCompatibilityInformation,
|
||
|
&lfh_flag,
|
||
|
sizeof(lfh_flag));
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
void EnableTerminationOnHeapCorruption() {
|
||
|
// Ignore the result code. Supported on XP SP3 and Vista.
|
||
|
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
|
||
|
}
|
||
|
|
||
|
void EnableTerminationOnOutOfMemory() {
|
||
|
std::set_new_handler(&OnNoMemory);
|
||
|
}
|
||
|
|
||
|
HMODULE GetModuleFromAddress(void* address) {
|
||
|
HMODULE instance = NULL;
|
||
|
if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||
|
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||
|
static_cast<char*>(address),
|
||
|
&instance)) {
|
||
|
NOTREACHED();
|
||
|
}
|
||
|
return instance;
|
||
|
}
|
||
|
|
||
|
} // namespace base
|