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

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

Issue 84063004: Restructure sandbox code to reduce dependencies pulled in by intercept code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Pre-review cleanup. Created 7 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "sandbox/win/src/sandbox_nt_util.h" 5 #include "sandbox/win/src/sandbox_nt_util.h"
6 6
7 #include "base/win/pe_image.h" 7 #include "base/win/pe_image.h"
8 #include "sandbox/win/src/sandbox_factory.h" 8 #include "sandbox/win/src/sandbox_factory.h"
9 #include "sandbox/win/src/target_services.h" 9 #include "sandbox/win/src/target_services.h"
10 10
11 namespace sandbox { 11 namespace sandbox {
12 12
13 // This is the list of all imported symbols from ntdll.dll. 13 // This is the list of all imported symbols from ntdll.dll.
14 SANDBOX_INTERCEPT NtExports g_nt = { NULL }; 14 SANDBOX_INTERCEPT NtExports g_nt;
15 15
16 } // namespace sandbox 16 } // namespace sandbox
17 17
18 namespace { 18 namespace {
19 19
20 #if defined(_WIN64) 20 #if defined(_WIN64)
21 void* AllocateNearTo(void* source, size_t size) { 21 void* AllocateNearTo(void* source, size_t size) {
22 using sandbox::g_nt; 22 using sandbox::g_nt;
23 23
24 // Start with 1 GB above the source. 24 // Start with 1 GB above the source.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 if (!NT_SUCCESS(ret)) 97 if (!NT_SUCCESS(ret))
98 return NULL; 98 return NULL;
99 return base; 99 return base;
100 } 100 }
101 #endif // defined(_WIN64). 101 #endif // defined(_WIN64).
102 102
103 } // namespace. 103 } // namespace.
104 104
105 namespace sandbox { 105 namespace sandbox {
106 106
107 // Handle for our private heap. 107 // This is the list of all imported symbols from ntdll.dll.
108 void* g_heap = NULL; 108 SANDBOX_INTERCEPT NtExports g_nt;
rvargas (doing something else) 2013/11/27 23:53:51 This is already defined up there
robertshield 2013/11/29 01:21:26 Done.
109 109
110 SANDBOX_INTERCEPT HANDLE g_shared_section; 110 SANDBOX_INTERCEPT HANDLE g_shared_section;
111 SANDBOX_INTERCEPT size_t g_shared_IPC_size = 0; 111 SANDBOX_INTERCEPT size_t g_shared_IPC_size = 0;
112 SANDBOX_INTERCEPT size_t g_shared_policy_size = 0; 112 SANDBOX_INTERCEPT size_t g_shared_policy_size = 0;
113 113
114 void* volatile g_shared_policy_memory = NULL; 114 void* volatile g_shared_policy_memory = NULL;
115 void* volatile g_shared_IPC_memory = NULL; 115 void* volatile g_shared_IPC_memory = NULL;
116 116
117 // Both the IPC and the policy share a single region of memory in which the IPC 117 // Both the IPC and the policy share a single region of memory in which the IPC
118 // memory is first and the policy memory is last. 118 // memory is first and the policy memory is last.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 return NULL; 150 return NULL;
151 return g_shared_IPC_memory; 151 return g_shared_IPC_memory;
152 } 152 }
153 153
154 void* GetGlobalPolicyMemory() { 154 void* GetGlobalPolicyMemory() {
155 if (!MapGlobalMemory()) 155 if (!MapGlobalMemory())
156 return NULL; 156 return NULL;
157 return g_shared_policy_memory; 157 return g_shared_policy_memory;
158 } 158 }
159 159
160 // Handle for our private heap.
161 void* g_heap = NULL;
rvargas (doing something else) 2013/11/27 23:53:51 don't move this to the middle of the file. The com
robertshield 2013/11/29 01:21:26 Done.
162
160 bool InitHeap() { 163 bool InitHeap() {
161 if (!g_heap) { 164 if (!g_heap) {
162 // Create a new heap using default values for everything. 165 // Create a new heap using default values for everything.
163 void* heap = g_nt.RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL); 166 void* heap = g_nt.RtlCreateHeap(HEAP_GROWABLE, NULL, 0, 0, NULL, NULL);
164 if (!heap) 167 if (!heap)
165 return false; 168 return false;
166 169
167 if (NULL != _InterlockedCompareExchangePointer(&g_heap, heap, NULL)) { 170 if (NULL != _InterlockedCompareExchangePointer(&g_heap, heap, NULL)) {
168 // Somebody beat us to the memory setup. 171 // Somebody beat us to the memory setup.
169 g_nt.RtlDestroyHeap(heap); 172 g_nt.RtlDestroyHeap(heap);
(...skipping 28 matching lines...) Expand all
198 bool ValidParameter(void* buffer, size_t size, RequiredAccess intent) { 201 bool ValidParameter(void* buffer, size_t size, RequiredAccess intent) {
199 DCHECK_NT(size); 202 DCHECK_NT(size);
200 __try { 203 __try {
201 TouchMemory(buffer, size, intent); 204 TouchMemory(buffer, size, intent);
202 } __except(EXCEPTION_EXECUTE_HANDLER) { 205 } __except(EXCEPTION_EXECUTE_HANDLER) {
203 return false; 206 return false;
204 } 207 }
205 return true; 208 return true;
206 } 209 }
207 210
208 NTSTATUS CopyData(void* destination, const void* source, size_t bytes) {
rvargas (doing something else) 2013/11/27 23:53:51 I presume this is being moved to nt_util_base. I h
rvargas (doing something else) 2013/11/27 23:53:51 After looking at the whole patch I see that interc
rvargas (doing something else) 2013/11/27 23:58:52 There is nt!memcpy (at least on Win7 but i expect
robertshield 2013/11/29 01:21:26 Done.
robertshield 2013/11/29 01:21:26 Done.
robertshield 2013/11/29 01:21:26 And this solves all known problems. Using nt's mem
209 NTSTATUS ret = STATUS_SUCCESS;
210 __try {
211 if (SandboxFactory::GetTargetServices()->GetState()->InitCalled()) {
212 memcpy(destination, source, bytes);
213 } else {
214 const char* from = reinterpret_cast<const char*>(source);
215 char* to = reinterpret_cast<char*>(destination);
216 for (size_t i = 0; i < bytes; i++) {
217 to[i] = from[i];
218 }
219 }
220 } __except(EXCEPTION_EXECUTE_HANDLER) {
221 ret = GetExceptionCode();
222 }
223 return ret;
224 }
225
226 // Hacky code... replace with AllocAndCopyObjectAttributes.
227 NTSTATUS AllocAndCopyName(const OBJECT_ATTRIBUTES* in_object,
228 wchar_t** out_name, uint32* attributes,
229 HANDLE* root) {
230 if (!InitHeap())
231 return STATUS_NO_MEMORY;
232
233 DCHECK_NT(out_name);
234 *out_name = NULL;
235 NTSTATUS ret = STATUS_UNSUCCESSFUL;
236 __try {
237 do {
238 if (in_object->RootDirectory != static_cast<HANDLE>(0) && !root)
239 break;
240 if (NULL == in_object->ObjectName)
241 break;
242 if (NULL == in_object->ObjectName->Buffer)
243 break;
244
245 size_t size = in_object->ObjectName->Length + sizeof(wchar_t);
246 *out_name = new(NT_ALLOC) wchar_t[size/sizeof(wchar_t)];
247 if (NULL == *out_name)
248 break;
249
250 ret = CopyData(*out_name, in_object->ObjectName->Buffer,
251 size - sizeof(wchar_t));
252 if (!NT_SUCCESS(ret))
253 break;
254
255 (*out_name)[size / sizeof(wchar_t) - 1] = L'\0';
256
257 if (attributes)
258 *attributes = in_object->Attributes;
259
260 if (root)
261 *root = in_object->RootDirectory;
262 ret = STATUS_SUCCESS;
263 } while (false);
264 } __except(EXCEPTION_EXECUTE_HANDLER) {
265 ret = GetExceptionCode();
266 }
267
268 if (!NT_SUCCESS(ret) && *out_name) {
269 operator delete(*out_name, NT_ALLOC);
270 *out_name = NULL;
271 }
272
273 return ret;
274 }
275
276 NTSTATUS GetProcessId(HANDLE process, ULONG *process_id) { 211 NTSTATUS GetProcessId(HANDLE process, ULONG *process_id) {
277 PROCESS_BASIC_INFORMATION proc_info; 212 PROCESS_BASIC_INFORMATION proc_info;
278 ULONG bytes_returned; 213 ULONG bytes_returned;
279 214
280 NTSTATUS ret = g_nt.QueryInformationProcess(process, ProcessBasicInformation, 215 NTSTATUS ret = g_nt.QueryInformationProcess(process, ProcessBasicInformation,
281 &proc_info, sizeof(proc_info), 216 &proc_info, sizeof(proc_info),
282 &bytes_returned); 217 &bytes_returned);
283 if (!NT_SUCCESS(ret) || sizeof(proc_info) != bytes_returned) 218 if (!NT_SUCCESS(ret) || sizeof(proc_info) != bytes_returned)
284 return ret; 219 return ret;
285 220
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 } 359 }
425 if (!NT_SUCCESS(ret)) { 360 if (!NT_SUCCESS(ret)) {
426 operator delete(section_name, NT_ALLOC); 361 operator delete(section_name, NT_ALLOC);
427 return NULL; 362 return NULL;
428 } 363 }
429 364
430 return reinterpret_cast<UNICODE_STRING*>(section_name); 365 return reinterpret_cast<UNICODE_STRING*>(section_name);
431 } 366 }
432 } 367 }
433 368
434 UNICODE_STRING* ExtractModuleName(const UNICODE_STRING* module_path) {
435 if ((!module_path) || (!module_path->Buffer))
436 return NULL;
437
438 wchar_t* sep = NULL;
439 int start_pos = module_path->Length / sizeof(wchar_t) - 1;
440 int ix = start_pos;
441
442 for (; ix >= 0; --ix) {
443 if (module_path->Buffer[ix] == L'\\') {
444 sep = &module_path->Buffer[ix];
445 break;
446 }
447 }
448
449 // Ends with path separator. Not a valid module name.
450 if ((ix == start_pos) && sep)
451 return NULL;
452
453 // No path separator found. Use the entire name.
454 if (!sep) {
455 sep = &module_path->Buffer[-1];
456 }
457
458 // Add one to the size so we can null terminate the string.
459 size_t size_bytes = (start_pos - ix + 1) * sizeof(wchar_t);
460
461 // Based on the code above, size_bytes should always be small enough
462 // to make the static_cast below safe.
463 DCHECK_NT(kuint16max > size_bytes);
464 char* str_buffer = new(NT_ALLOC) char[size_bytes + sizeof(UNICODE_STRING)];
465 if (!str_buffer)
466 return NULL;
467
468 UNICODE_STRING* out_string = reinterpret_cast<UNICODE_STRING*>(str_buffer);
469 out_string->Buffer = reinterpret_cast<wchar_t*>(&out_string[1]);
470 out_string->Length = static_cast<USHORT>(size_bytes - sizeof(wchar_t));
471 out_string->MaximumLength = static_cast<USHORT>(size_bytes);
472
473 NTSTATUS ret = CopyData(out_string->Buffer, &sep[1], out_string->Length);
474 if (!NT_SUCCESS(ret)) {
475 operator delete(out_string, NT_ALLOC);
476 return NULL;
477 }
478
479 out_string->Buffer[out_string->Length / sizeof(wchar_t)] = L'\0';
480 return out_string;
481 }
482
483 NTSTATUS AutoProtectMemory::ChangeProtection(void* address, size_t bytes, 369 NTSTATUS AutoProtectMemory::ChangeProtection(void* address, size_t bytes,
484 ULONG protect) { 370 ULONG protect) {
485 DCHECK_NT(!changed_); 371 DCHECK_NT(!changed_);
486 SIZE_T new_bytes = bytes; 372 SIZE_T new_bytes = bytes;
487 NTSTATUS ret = g_nt.ProtectVirtualMemory(NtCurrentProcess, &address, 373 NTSTATUS ret = g_nt.ProtectVirtualMemory(NtCurrentProcess, &address,
488 &new_bytes, protect, &old_protect_); 374 &new_bytes, protect, &old_protect_);
489 if (NT_SUCCESS(ret)) { 375 if (NT_SUCCESS(ret)) {
490 changed_ = true; 376 changed_ = true;
491 address_ = address; 377 address_ = address;
492 bytes_ = new_bytes; 378 bytes_ = new_bytes;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 UNREFERENCED_PARAMETER(type); 479 UNREFERENCED_PARAMETER(type);
594 return buffer; 480 return buffer;
595 } 481 }
596 482
597 void __cdecl operator delete(void* memory, void* buffer, 483 void __cdecl operator delete(void* memory, void* buffer,
598 sandbox::AllocationType type) { 484 sandbox::AllocationType type) {
599 UNREFERENCED_PARAMETER(memory); 485 UNREFERENCED_PARAMETER(memory);
600 UNREFERENCED_PARAMETER(buffer); 486 UNREFERENCED_PARAMETER(buffer);
601 UNREFERENCED_PARAMETER(type); 487 UNREFERENCED_PARAMETER(type);
602 } 488 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698