diff options
author | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-28 17:40:24 +0000 |
---|---|---|
committer | rsesek@chromium.org <rsesek@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-28 17:40:24 +0000 |
commit | bac984109266ad0c8ce11a6930a81303de528455 (patch) | |
tree | c1a21d15b0c73fadb16671f7d47bd3e57a350d69 /base/process/memory_win.cc | |
parent | ea1a2c532ad5ccf3d51165e06165d76a93a0806a (diff) | |
download | chromium_src-bac984109266ad0c8ce11a6930a81303de528455.zip chromium_src-bac984109266ad0c8ce11a6930a81303de528455.tar.gz chromium_src-bac984109266ad0c8ce11a6930a81303de528455.tar.bz2 |
Split memory-related routines out of base/process_util.h into base/process/memory.h.
BUG=242290
R=brettw@chromium.org
Review URL: https://codereview.chromium.org/17910003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209172 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process/memory_win.cc')
-rw-r--r-- | base/process/memory_win.cc | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/base/process/memory_win.cc b/base/process/memory_win.cc new file mode 100644 index 0000000..c53a1be --- /dev/null +++ b/base/process/memory_win.cc @@ -0,0 +1,85 @@ +// 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 |