• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/process/memory.h"
6 
7 #include <psapi.h>
8 
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 
12 namespace base {
13 
14 namespace {
15 
OnNoMemory()16 void OnNoMemory() {
17   // Kill the process. This is important for security, since WebKit doesn't
18   // NULL-check many memory allocations. If a malloc fails, returns NULL, and
19   // the buffer is then used, it provides a handy mapping of memory starting at
20   // address 0 for an attacker to utilize.
21   __debugbreak();
22   _exit(1);
23 }
24 
25 // HeapSetInformation function pointer.
26 typedef BOOL (WINAPI* HeapSetFn)(HANDLE, HEAP_INFORMATION_CLASS, PVOID, SIZE_T);
27 
28 }  // namespace
29 
EnableLowFragmentationHeap()30 bool EnableLowFragmentationHeap() {
31   HMODULE kernel32 = GetModuleHandle(L"kernel32.dll");
32   HeapSetFn heap_set = reinterpret_cast<HeapSetFn>(GetProcAddress(
33       kernel32,
34       "HeapSetInformation"));
35 
36   // On Windows 2000, the function is not exported. This is not a reason to
37   // fail.
38   if (!heap_set)
39     return true;
40 
41   unsigned number_heaps = GetProcessHeaps(0, NULL);
42   if (!number_heaps)
43     return false;
44 
45   // Gives us some extra space in the array in case a thread is creating heaps
46   // at the same time we're querying them.
47   static const int MARGIN = 8;
48   scoped_ptr<HANDLE[]> heaps(new HANDLE[number_heaps + MARGIN]);
49   number_heaps = GetProcessHeaps(number_heaps + MARGIN, heaps.get());
50   if (!number_heaps)
51     return false;
52 
53   for (unsigned i = 0; i < number_heaps; ++i) {
54     ULONG lfh_flag = 2;
55     // Don't bother with the result code. It may fails on heaps that have the
56     // HEAP_NO_SERIALIZE flag. This is expected and not a problem at all.
57     heap_set(heaps[i],
58              HeapCompatibilityInformation,
59              &lfh_flag,
60              sizeof(lfh_flag));
61   }
62   return true;
63 }
64 
EnableTerminationOnHeapCorruption()65 void EnableTerminationOnHeapCorruption() {
66   // Ignore the result code. Supported on XP SP3 and Vista.
67   HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
68 }
69 
EnableTerminationOnOutOfMemory()70 void EnableTerminationOnOutOfMemory() {
71   std::set_new_handler(&OnNoMemory);
72 }
73 
GetModuleFromAddress(void * address)74 HMODULE GetModuleFromAddress(void* address) {
75   HMODULE instance = NULL;
76   if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
77                             GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
78                             static_cast<char*>(address),
79                             &instance)) {
80     NOTREACHED();
81   }
82   return instance;
83 }
84 
85 // TODO(b.kelemen): implement it with the required semantics. On Linux this is
86 // implemented with a weak symbol that is overridden by tcmalloc. This is
87 // neccessary because base cannot have a direct dependency on tcmalloc. Since
88 // weak symbols are not supported on Windows this will involve some build time
89 // magic, much like what is done for libcrt in order to override the allocation
90 // functions.
UncheckedMalloc(size_t size,void ** result)91 bool UncheckedMalloc(size_t size, void** result) {
92   *result = malloc(size);
93   return *result != NULL;
94 }
95 
96 }  // namespace base
97