Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Side by Side Diff: sandbox/win/src/interception_agent.cc

Issue 1851213002: Remove sandbox on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix nacl compile issues Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sandbox/win/src/interception_agent.h ('k') | sandbox/win/src/interception_internal.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2010 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 // For information about interceptions as a whole see
6 // http://dev.chromium.org/developers/design-documents/sandbox .
7
8 #include "sandbox/win/src/interception_agent.h"
9
10 #include <stddef.h>
11
12 #include "sandbox/win/src/eat_resolver.h"
13 #include "sandbox/win/src/interception_internal.h"
14 #include "sandbox/win/src/interceptors.h"
15 #include "sandbox/win/src/sandbox_nt_util.h"
16 #include "sandbox/win/src/sidestep_resolver.h"
17
18 namespace {
19
20 // Returns true if target lies between base and base + range.
21 bool IsWithinRange(const void* base, size_t range, const void* target) {
22 const char* end = reinterpret_cast<const char*>(base) + range;
23 return reinterpret_cast<const char*>(target) < end;
24 }
25
26 } // namespace
27
28 namespace sandbox {
29
30 // This is the list of all imported symbols from ntdll.dll.
31 SANDBOX_INTERCEPT NtExports g_nt;
32
33 // The list of intercepted functions back-pointers.
34 SANDBOX_INTERCEPT OriginalFunctions g_originals;
35
36 // Memory buffer mapped from the parent, with the list of interceptions.
37 SANDBOX_INTERCEPT SharedMemory* g_interceptions = NULL;
38
39 InterceptionAgent* InterceptionAgent::GetInterceptionAgent() {
40 static InterceptionAgent* s_singleton = NULL;
41 if (!s_singleton) {
42 if (!g_interceptions)
43 return NULL;
44
45 size_t array_bytes = g_interceptions->num_intercepted_dlls * sizeof(void*);
46 s_singleton = reinterpret_cast<InterceptionAgent*>(
47 new(NT_ALLOC) char[array_bytes + sizeof(InterceptionAgent)]);
48
49 bool success = s_singleton->Init(g_interceptions);
50 if (!success) {
51 operator delete(s_singleton, NT_ALLOC);
52 s_singleton = NULL;
53 }
54 }
55 return s_singleton;
56 }
57
58 bool InterceptionAgent::Init(SharedMemory* shared_memory) {
59 interceptions_ = shared_memory;
60 for (int i = 0 ; i < shared_memory->num_intercepted_dlls; i++)
61 dlls_[i] = NULL;
62 return true;
63 }
64
65 bool InterceptionAgent::DllMatch(const UNICODE_STRING* full_path,
66 const UNICODE_STRING* name,
67 const DllPatchInfo* dll_info) {
68 UNICODE_STRING current_name;
69 current_name.Length = static_cast<USHORT>(g_nt.wcslen(dll_info->dll_name) *
70 sizeof(wchar_t));
71 current_name.MaximumLength = current_name.Length;
72 current_name.Buffer = const_cast<wchar_t*>(dll_info->dll_name);
73
74 BOOLEAN case_insensitive = TRUE;
75 if (full_path &&
76 !g_nt.RtlCompareUnicodeString(&current_name, full_path, case_insensitive))
77 return true;
78
79 if (name &&
80 !g_nt.RtlCompareUnicodeString(&current_name, name, case_insensitive))
81 return true;
82
83 return false;
84 }
85
86 bool InterceptionAgent::OnDllLoad(const UNICODE_STRING* full_path,
87 const UNICODE_STRING* name,
88 void* base_address) {
89 DllPatchInfo* dll_info = interceptions_->dll_list;
90 int i = 0;
91 for (; i < interceptions_->num_intercepted_dlls; i++) {
92 if (DllMatch(full_path, name, dll_info))
93 break;
94
95 dll_info = reinterpret_cast<DllPatchInfo*>(
96 reinterpret_cast<char*>(dll_info) + dll_info->record_bytes);
97 }
98
99 // Return now if the dll is not in our list of interest.
100 if (i == interceptions_->num_intercepted_dlls)
101 return true;
102
103 // The dll must be unloaded.
104 if (dll_info->unload_module)
105 return false;
106
107 // Purify causes this condition to trigger.
108 if (dlls_[i])
109 return true;
110
111 size_t buffer_bytes = offsetof(DllInterceptionData, thunks) +
112 dll_info->num_functions * sizeof(ThunkData);
113 dlls_[i] = reinterpret_cast<DllInterceptionData*>(
114 new(NT_PAGE, base_address) char[buffer_bytes]);
115
116 DCHECK_NT(dlls_[i]);
117 if (!dlls_[i])
118 return true;
119
120 dlls_[i]->data_bytes = buffer_bytes;
121 dlls_[i]->num_thunks = 0;
122 dlls_[i]->base = base_address;
123 dlls_[i]->used_bytes = offsetof(DllInterceptionData, thunks);
124
125 VERIFY(PatchDll(dll_info, dlls_[i]));
126
127 ULONG old_protect;
128 SIZE_T real_size = buffer_bytes;
129 void* to_protect = dlls_[i];
130 VERIFY_SUCCESS(g_nt.ProtectVirtualMemory(NtCurrentProcess, &to_protect,
131 &real_size, PAGE_EXECUTE_READ,
132 &old_protect));
133 return true;
134 }
135
136 void InterceptionAgent::OnDllUnload(void* base_address) {
137 for (int i = 0; i < interceptions_->num_intercepted_dlls; i++) {
138 if (dlls_[i] && dlls_[i]->base == base_address) {
139 operator delete(dlls_[i], NT_PAGE);
140 dlls_[i] = NULL;
141 break;
142 }
143 }
144 }
145
146 // TODO(rvargas): We have to deal with prebinded dlls. I see two options: change
147 // the timestamp of the patched dll, or modify the info on the prebinded dll.
148 // the first approach messes matching of debug symbols, the second one is more
149 // complicated.
150 bool InterceptionAgent::PatchDll(const DllPatchInfo* dll_info,
151 DllInterceptionData* thunks) {
152 DCHECK_NT(NULL != thunks);
153 DCHECK_NT(NULL != dll_info);
154
155 const FunctionInfo* function = reinterpret_cast<const FunctionInfo*>(
156 reinterpret_cast<const char*>(dll_info) + dll_info->offset_to_functions);
157
158 for (int i = 0; i < dll_info->num_functions; i++) {
159 if (!IsWithinRange(dll_info, dll_info->record_bytes, function->function)) {
160 NOTREACHED_NT();
161 return false;
162 }
163
164 ResolverThunk* resolver = GetResolver(function->type);
165 if (!resolver)
166 return false;
167
168 const char* interceptor = function->function +
169 g_nt.strlen(function->function) + 1;
170
171 if (!IsWithinRange(function, function->record_bytes, interceptor) ||
172 !IsWithinRange(dll_info, dll_info->record_bytes, interceptor)) {
173 NOTREACHED_NT();
174 return false;
175 }
176
177 NTSTATUS ret = resolver->Setup(thunks->base,
178 interceptions_->interceptor_base,
179 function->function,
180 interceptor,
181 function->interceptor_address,
182 &thunks->thunks[i],
183 sizeof(ThunkData),
184 NULL);
185 if (!NT_SUCCESS(ret)) {
186 NOTREACHED_NT();
187 return false;
188 }
189
190 DCHECK_NT(!g_originals[function->id]);
191 g_originals[function->id] = &thunks->thunks[i];
192
193 thunks->num_thunks++;
194 thunks->used_bytes += sizeof(ThunkData);
195
196 function = reinterpret_cast<const FunctionInfo*>(
197 reinterpret_cast<const char*>(function) + function->record_bytes);
198 }
199
200 return true;
201 }
202
203 // This method is called from within the loader lock
204 ResolverThunk* InterceptionAgent::GetResolver(InterceptionType type) {
205 static EatResolverThunk* eat_resolver = NULL;
206 static SidestepResolverThunk* sidestep_resolver = NULL;
207 static SmartSidestepResolverThunk* smart_sidestep_resolver = NULL;
208
209 if (!eat_resolver)
210 eat_resolver = new(NT_ALLOC) EatResolverThunk;
211
212 #if !defined(_WIN64)
213 // Sidestep is not supported for x64.
214 if (!sidestep_resolver)
215 sidestep_resolver = new(NT_ALLOC) SidestepResolverThunk;
216
217 if (!smart_sidestep_resolver)
218 smart_sidestep_resolver = new(NT_ALLOC) SmartSidestepResolverThunk;
219 #endif
220
221 switch (type) {
222 case INTERCEPTION_EAT:
223 return eat_resolver;
224 case INTERCEPTION_SIDESTEP:
225 return sidestep_resolver;
226 case INTERCEPTION_SMART_SIDESTEP:
227 return smart_sidestep_resolver;
228 default:
229 NOTREACHED_NT();
230 }
231
232 return NULL;
233 }
234
235 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/interception_agent.h ('k') | sandbox/win/src/interception_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698