1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/agent/asan/windows_heap_adapter.h"
16 :
17 : #include <algorithm>
18 :
19 : #include "base/logging.h"
20 : #include "syzygy/agent/asan/heap_manager.h"
21 :
22 : namespace agent {
23 : namespace asan {
24 :
25 : namespace {
26 :
27 : // Cast a heap ID into a HANDLE.
28 : // @param heap_id The heap ID to cast.
29 : // @returns the heap ID casted as an HANDLE.
30 E : HANDLE HeapIdToHandle(HeapManagerInterface::HeapId heap_id) {
31 E : DCHECK_NE(static_cast<HeapManagerInterface::HeapId>(NULL), heap_id);
32 : static_assert(sizeof(HANDLE) == sizeof(HeapManagerInterface::HeapId),
33 : "Size of HANDLE and HeapId are different.");
34 E : return reinterpret_cast<HANDLE>(heap_id);
35 E : }
36 :
37 : // Cast a HANDLE into a heap ID.
38 : // @param heap The HANDLE to cast.
39 : // @returns the HANDLE casted as a heap ID.
40 E : HeapManagerInterface::HeapId HandleToHeapId(HANDLE heap) {
41 E : DCHECK_NE(static_cast<HANDLE>(NULL), heap);
42 E : return reinterpret_cast<HeapManagerInterface::HeapId>(heap);
43 E : }
44 :
45 : } // namespace
46 :
47 : HeapManagerInterface* WindowsHeapAdapter::heap_manager_ = NULL;
48 :
49 E : void WindowsHeapAdapter::SetUp(HeapManagerInterface* heap_manager) {
50 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager);
51 E : DCHECK_EQ(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
52 E : heap_manager_ = heap_manager;
53 E : }
54 :
55 E : void WindowsHeapAdapter::TearDown() {
56 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
57 E : heap_manager_ = NULL;
58 E : }
59 :
60 : HANDLE WindowsHeapAdapter::HeapCreate(DWORD options,
61 : SIZE_T initial_size,
62 E : SIZE_T maximum_size) {
63 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
64 E : return HeapIdToHandle(heap_manager_->CreateHeap());
65 E : }
66 :
67 E : BOOL WindowsHeapAdapter::HeapDestroy(HANDLE heap) {
68 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
69 E : return heap_manager_->DestroyHeap(HandleToHeapId(heap));
70 E : }
71 :
72 E : LPVOID WindowsHeapAdapter::HeapAlloc(HANDLE heap, DWORD flags, SIZE_T bytes) {
73 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
74 E : LPVOID alloc = heap_manager_->Allocate(HandleToHeapId(heap), bytes);
75 E : if (alloc != NULL && (flags & HEAP_ZERO_MEMORY) != 0 && bytes > 0)
76 E : ::memset(alloc, 0, bytes);
77 E : return alloc;
78 E : }
79 :
80 : LPVOID WINAPI WindowsHeapAdapter::HeapReAlloc(HANDLE heap,
81 : DWORD flags,
82 : LPVOID mem,
83 E : SIZE_T bytes) {
84 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
85 : // Always fail in-place reallocation requests.
86 E : if ((flags & HEAP_REALLOC_IN_PLACE_ONLY) != 0)
87 E : return NULL;
88 :
89 E : void* new_mem = WindowsHeapAdapter::HeapAlloc(heap, flags, bytes);
90 : // Bail early if the new allocation didn't succeed and avoid freeing the
91 : // existing allocation.
92 E : if (new_mem == NULL)
93 E : return NULL;
94 :
95 E : if (mem != NULL) {
96 E : ::memcpy(new_mem, mem, std::min(bytes, HeapSize(heap, 0, mem)));
97 E : WindowsHeapAdapter::HeapFree(heap, flags, mem);
98 : }
99 :
100 E : return new_mem;
101 E : }
102 :
103 E : BOOL WindowsHeapAdapter::HeapFree(HANDLE heap, DWORD flags, LPVOID mem) {
104 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
105 E : return heap_manager_->Free(HandleToHeapId(heap), mem);
106 E : }
107 :
108 E : SIZE_T WindowsHeapAdapter::HeapSize(HANDLE heap, DWORD flags, LPCVOID mem) {
109 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
110 E : return heap_manager_->Size(HandleToHeapId(heap), mem);
111 E : }
112 :
113 E : BOOL WindowsHeapAdapter::HeapValidate(HANDLE heap, DWORD flags, LPCVOID mem) {
114 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
115 : // This function isn't supported by the by the heap managers and doesn't
116 : // really makes sense in an Asan build.
117 E : return TRUE;
118 E : }
119 :
120 E : SIZE_T WindowsHeapAdapter::HeapCompact(HANDLE heap, DWORD flags) {
121 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
122 : // This function isn't supported by the by the heap managers and doesn't
123 : // really makes sense in an Asan build.
124 E : return 0;
125 E : }
126 :
127 E : BOOL WindowsHeapAdapter::HeapLock(HANDLE heap) {
128 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
129 E : heap_manager_->Lock(HandleToHeapId(heap));
130 E : return TRUE;
131 E : }
132 :
133 E : BOOL WindowsHeapAdapter::HeapUnlock(HANDLE heap) {
134 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
135 E : heap_manager_->Unlock(HandleToHeapId(heap));
136 E : return TRUE;
137 E : }
138 :
139 E : BOOL WindowsHeapAdapter::HeapWalk(HANDLE heap, LPPROCESS_HEAP_ENTRY entry) {
140 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
141 : // TODO(sebmarchand): Add walking support to the heaps if needed.
142 E : return FALSE;
143 E : }
144 :
145 : BOOL WindowsHeapAdapter::HeapSetInformation(HANDLE heap,
146 : HEAP_INFORMATION_CLASS info_class,
147 : PVOID info,
148 E : SIZE_T info_length) {
149 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
150 : // This function isn't supported by the by the heap managers and doesn't
151 : // really makes sense in an Asan build.
152 : // Return true to avoid crashing if a process try to set some heap information
153 : // at startup.
154 E : return TRUE;
155 E : }
156 :
157 : BOOL WindowsHeapAdapter::HeapQueryInformation(HANDLE heap,
158 : HEAP_INFORMATION_CLASS info_class,
159 : PVOID info,
160 : SIZE_T info_length,
161 E : PSIZE_T return_length) {
162 E : DCHECK_NE(reinterpret_cast<HeapManagerInterface*>(NULL), heap_manager_);
163 : // This function isn't supported by the by the heap managers and doesn't
164 : // really makes sense in an Asan build.
165 E : return FALSE;
166 E : }
167 :
168 : } // namespace asan
169 : } // namespace agent
|