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

Side by Side Diff: sandbox/win/src/process_thread_interception.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/process_thread_interception.h ('k') | sandbox/win/src/process_thread_policy.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) 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 "sandbox/win/src/process_thread_interception.h"
6
7 #include <stdint.h>
8 #include "base/win/windows_version.h"
9 #include "sandbox/win/src/crosscall_client.h"
10 #include "sandbox/win/src/ipc_tags.h"
11 #include "sandbox/win/src/policy_params.h"
12 #include "sandbox/win/src/policy_target.h"
13 #include "sandbox/win/src/sandbox_factory.h"
14 #include "sandbox/win/src/sandbox_nt_util.h"
15 #include "sandbox/win/src/sharedmem_ipc_client.h"
16 #include "sandbox/win/src/target_services.h"
17
18 namespace sandbox {
19
20 SANDBOX_INTERCEPT NtExports g_nt;
21
22 // Hooks NtOpenThread and proxy the call to the broker if it's trying to
23 // open a thread in the same process.
24 NTSTATUS WINAPI TargetNtOpenThread(NtOpenThreadFunction orig_OpenThread,
25 PHANDLE thread, ACCESS_MASK desired_access,
26 POBJECT_ATTRIBUTES object_attributes,
27 PCLIENT_ID client_id) {
28 NTSTATUS status = orig_OpenThread(thread, desired_access, object_attributes,
29 client_id);
30 if (NT_SUCCESS(status))
31 return status;
32
33 do {
34 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
35 break;
36 if (!client_id)
37 break;
38
39 uint32_t thread_id = 0;
40 bool should_break = false;
41 __try {
42 // We support only the calls for the current process
43 if (NULL != client_id->UniqueProcess)
44 should_break = true;
45
46 // Object attributes should be NULL or empty.
47 if (!should_break && NULL != object_attributes) {
48 if (0 != object_attributes->Attributes ||
49 NULL != object_attributes->ObjectName ||
50 NULL != object_attributes->RootDirectory ||
51 NULL != object_attributes->SecurityDescriptor ||
52 NULL != object_attributes->SecurityQualityOfService) {
53 should_break = true;
54 }
55 }
56
57 thread_id = static_cast<uint32_t>(
58 reinterpret_cast<ULONG_PTR>(client_id->UniqueThread));
59 } __except(EXCEPTION_EXECUTE_HANDLER) {
60 break;
61 }
62
63 if (should_break)
64 break;
65
66 if (!ValidParameter(thread, sizeof(HANDLE), WRITE))
67 break;
68
69 void* memory = GetGlobalIPCMemory();
70 if (NULL == memory)
71 break;
72
73 SharedMemIPCClient ipc(memory);
74 CrossCallReturn answer = {0};
75 ResultCode code = CrossCall(ipc, IPC_NTOPENTHREAD_TAG, desired_access,
76 thread_id, &answer);
77 if (SBOX_ALL_OK != code)
78 break;
79
80 if (!NT_SUCCESS(answer.nt_status))
81 // The nt_status here is most likely STATUS_INVALID_CID because
82 // in the broker we set the process id in the CID (client ID) param
83 // to be the current process. If you try to open a thread from another
84 // process you will get this INVALID_CID error. On the other hand, if you
85 // try to open a thread in your own process, it should return success.
86 // We don't want to return STATUS_INVALID_CID here, so we return the
87 // return of the original open thread status, which is most likely
88 // STATUS_ACCESS_DENIED.
89 break;
90
91 __try {
92 // Write the output parameters.
93 *thread = answer.handle;
94 } __except(EXCEPTION_EXECUTE_HANDLER) {
95 break;
96 }
97
98 return answer.nt_status;
99 } while (false);
100
101 return status;
102 }
103
104 // Hooks NtOpenProcess and proxy the call to the broker if it's trying to
105 // open the current process.
106 NTSTATUS WINAPI TargetNtOpenProcess(NtOpenProcessFunction orig_OpenProcess,
107 PHANDLE process, ACCESS_MASK desired_access,
108 POBJECT_ATTRIBUTES object_attributes,
109 PCLIENT_ID client_id) {
110 NTSTATUS status = orig_OpenProcess(process, desired_access, object_attributes,
111 client_id);
112 if (NT_SUCCESS(status))
113 return status;
114
115 do {
116 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
117 break;
118 if (!client_id)
119 break;
120
121 uint32_t process_id = 0;
122 bool should_break = false;
123 __try {
124 // Object attributes should be NULL or empty.
125 if (!should_break && NULL != object_attributes) {
126 if (0 != object_attributes->Attributes ||
127 NULL != object_attributes->ObjectName ||
128 NULL != object_attributes->RootDirectory ||
129 NULL != object_attributes->SecurityDescriptor ||
130 NULL != object_attributes->SecurityQualityOfService) {
131 should_break = true;
132 }
133 }
134
135 process_id = static_cast<uint32_t>(
136 reinterpret_cast<ULONG_PTR>(client_id->UniqueProcess));
137 } __except(EXCEPTION_EXECUTE_HANDLER) {
138 break;
139 }
140
141 if (should_break)
142 break;
143
144 if (!ValidParameter(process, sizeof(HANDLE), WRITE))
145 break;
146
147 void* memory = GetGlobalIPCMemory();
148 if (NULL == memory)
149 break;
150
151 SharedMemIPCClient ipc(memory);
152 CrossCallReturn answer = {0};
153 ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESS_TAG, desired_access,
154 process_id, &answer);
155 if (SBOX_ALL_OK != code)
156 break;
157
158 if (!NT_SUCCESS(answer.nt_status))
159 return answer.nt_status;
160
161 __try {
162 // Write the output parameters.
163 *process = answer.handle;
164 } __except(EXCEPTION_EXECUTE_HANDLER) {
165 break;
166 }
167
168 return answer.nt_status;
169 } while (false);
170
171 return status;
172 }
173
174
175 NTSTATUS WINAPI TargetNtOpenProcessToken(
176 NtOpenProcessTokenFunction orig_OpenProcessToken, HANDLE process,
177 ACCESS_MASK desired_access, PHANDLE token) {
178 NTSTATUS status = orig_OpenProcessToken(process, desired_access, token);
179 if (NT_SUCCESS(status))
180 return status;
181
182 do {
183 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
184 break;
185
186 if (CURRENT_PROCESS != process)
187 break;
188
189 if (!ValidParameter(token, sizeof(HANDLE), WRITE))
190 break;
191
192 void* memory = GetGlobalIPCMemory();
193 if (NULL == memory)
194 break;
195
196 SharedMemIPCClient ipc(memory);
197 CrossCallReturn answer = {0};
198 ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKEN_TAG, process,
199 desired_access, &answer);
200 if (SBOX_ALL_OK != code)
201 break;
202
203 if (!NT_SUCCESS(answer.nt_status))
204 return answer.nt_status;
205
206 __try {
207 // Write the output parameters.
208 *token = answer.handle;
209 } __except(EXCEPTION_EXECUTE_HANDLER) {
210 break;
211 }
212
213 return answer.nt_status;
214 } while (false);
215
216 return status;
217 }
218
219 NTSTATUS WINAPI TargetNtOpenProcessTokenEx(
220 NtOpenProcessTokenExFunction orig_OpenProcessTokenEx, HANDLE process,
221 ACCESS_MASK desired_access, ULONG handle_attributes, PHANDLE token) {
222 NTSTATUS status = orig_OpenProcessTokenEx(process, desired_access,
223 handle_attributes, token);
224 if (NT_SUCCESS(status))
225 return status;
226
227 do {
228 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
229 break;
230
231 if (CURRENT_PROCESS != process)
232 break;
233
234 if (!ValidParameter(token, sizeof(HANDLE), WRITE))
235 break;
236
237 void* memory = GetGlobalIPCMemory();
238 if (NULL == memory)
239 break;
240
241 SharedMemIPCClient ipc(memory);
242 CrossCallReturn answer = {0};
243 ResultCode code = CrossCall(ipc, IPC_NTOPENPROCESSTOKENEX_TAG, process,
244 desired_access, handle_attributes, &answer);
245 if (SBOX_ALL_OK != code)
246 break;
247
248 if (!NT_SUCCESS(answer.nt_status))
249 return answer.nt_status;
250
251 __try {
252 // Write the output parameters.
253 *token = answer.handle;
254 } __except(EXCEPTION_EXECUTE_HANDLER) {
255 break;
256 }
257
258 return answer.nt_status;
259 } while (false);
260
261 return status;
262 }
263
264 BOOL WINAPI TargetCreateProcessW(CreateProcessWFunction orig_CreateProcessW,
265 LPCWSTR application_name, LPWSTR command_line,
266 LPSECURITY_ATTRIBUTES process_attributes,
267 LPSECURITY_ATTRIBUTES thread_attributes,
268 BOOL inherit_handles, DWORD flags,
269 LPVOID environment, LPCWSTR current_directory,
270 LPSTARTUPINFOW startup_info,
271 LPPROCESS_INFORMATION process_information) {
272 if (SandboxFactory::GetTargetServices()->GetState()->IsCsrssConnected() &&
273 orig_CreateProcessW(application_name, command_line, process_attributes,
274 thread_attributes, inherit_handles, flags,
275 environment, current_directory, startup_info,
276 process_information)) {
277 return TRUE;
278 }
279
280 // We don't trust that the IPC can work this early.
281 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
282 return FALSE;
283
284 // Don't call GetLastError before InitCalled() succeeds because kernel32 may
285 // not be mapped yet.
286 DWORD original_error = ::GetLastError();
287
288 do {
289 if (!ValidParameter(process_information, sizeof(PROCESS_INFORMATION),
290 WRITE))
291 break;
292
293 void* memory = GetGlobalIPCMemory();
294 if (NULL == memory)
295 break;
296
297 const wchar_t* cur_dir = NULL;
298
299 wchar_t current_directory[MAX_PATH];
300 DWORD result = ::GetCurrentDirectory(MAX_PATH, current_directory);
301 if (0 != result && result < MAX_PATH)
302 cur_dir = current_directory;
303
304 SharedMemIPCClient ipc(memory);
305 CrossCallReturn answer = {0};
306
307 InOutCountedBuffer proc_info(process_information,
308 sizeof(PROCESS_INFORMATION));
309
310 ResultCode code = CrossCall(ipc, IPC_CREATEPROCESSW_TAG, application_name,
311 command_line, cur_dir, proc_info, &answer);
312 if (SBOX_ALL_OK != code)
313 break;
314
315 ::SetLastError(answer.win32_result);
316 if (ERROR_SUCCESS != answer.win32_result)
317 return FALSE;
318
319 return TRUE;
320 } while (false);
321
322 ::SetLastError(original_error);
323 return FALSE;
324 }
325
326 BOOL WINAPI TargetCreateProcessA(CreateProcessAFunction orig_CreateProcessA,
327 LPCSTR application_name, LPSTR command_line,
328 LPSECURITY_ATTRIBUTES process_attributes,
329 LPSECURITY_ATTRIBUTES thread_attributes,
330 BOOL inherit_handles, DWORD flags,
331 LPVOID environment, LPCSTR current_directory,
332 LPSTARTUPINFOA startup_info,
333 LPPROCESS_INFORMATION process_information) {
334 if (SandboxFactory::GetTargetServices()->GetState()->IsCsrssConnected() &&
335 orig_CreateProcessA(application_name, command_line, process_attributes,
336 thread_attributes, inherit_handles, flags,
337 environment, current_directory, startup_info,
338 process_information)) {
339 return TRUE;
340 }
341
342 // We don't trust that the IPC can work this early.
343 if (!SandboxFactory::GetTargetServices()->GetState()->InitCalled())
344 return FALSE;
345
346 // Don't call GetLastError before InitCalled() succeeds because kernel32 may
347 // not be mapped yet.
348 DWORD original_error = ::GetLastError();
349
350 do {
351 if (!ValidParameter(process_information, sizeof(PROCESS_INFORMATION),
352 WRITE))
353 break;
354
355 void* memory = GetGlobalIPCMemory();
356 if (NULL == memory)
357 break;
358
359 // Convert the input params to unicode.
360 UNICODE_STRING *cmd_unicode = NULL;
361 UNICODE_STRING *app_unicode = NULL;
362 if (command_line) {
363 cmd_unicode = AnsiToUnicode(command_line);
364 if (!cmd_unicode)
365 break;
366 }
367
368 if (application_name) {
369 app_unicode = AnsiToUnicode(application_name);
370 if (!app_unicode) {
371 operator delete(cmd_unicode, NT_ALLOC);
372 break;
373 }
374 }
375
376 const wchar_t* cmd_line = cmd_unicode ? cmd_unicode->Buffer : NULL;
377 const wchar_t* app_name = app_unicode ? app_unicode->Buffer : NULL;
378 const wchar_t* cur_dir = NULL;
379
380 wchar_t current_directory[MAX_PATH];
381 DWORD result = ::GetCurrentDirectory(MAX_PATH, current_directory);
382 if (0 != result && result < MAX_PATH)
383 cur_dir = current_directory;
384
385 SharedMemIPCClient ipc(memory);
386 CrossCallReturn answer = {0};
387
388 InOutCountedBuffer proc_info(process_information,
389 sizeof(PROCESS_INFORMATION));
390
391 ResultCode code = CrossCall(ipc, IPC_CREATEPROCESSW_TAG, app_name,
392 cmd_line, cur_dir, proc_info, &answer);
393
394 operator delete(cmd_unicode, NT_ALLOC);
395 operator delete(app_unicode, NT_ALLOC);
396
397 if (SBOX_ALL_OK != code)
398 break;
399
400 ::SetLastError(answer.win32_result);
401 if (ERROR_SUCCESS != answer.win32_result)
402 return FALSE;
403
404 return TRUE;
405 } while (false);
406
407 ::SetLastError(original_error);
408 return FALSE;
409 }
410
411 HANDLE WINAPI TargetCreateThread(CreateThreadFunction orig_CreateThread,
412 LPSECURITY_ATTRIBUTES thread_attributes,
413 SIZE_T stack_size,
414 LPTHREAD_START_ROUTINE start_address,
415 LPVOID parameter,
416 DWORD creation_flags,
417 LPDWORD thread_id) {
418 HANDLE hThread = NULL;
419
420 TargetServices* target_services = SandboxFactory::GetTargetServices();
421 if (NULL == target_services ||
422 target_services->GetState()->IsCsrssConnected()) {
423 hThread = orig_CreateThread(thread_attributes, stack_size, start_address,
424 parameter, creation_flags, thread_id);
425 if (hThread) {
426 return hThread;
427 }
428 }
429
430 DWORD original_error = ::GetLastError();
431 do {
432 if (NULL == target_services)
433 break;
434
435 // We don't trust that the IPC can work this early.
436 if (!target_services->GetState()->InitCalled())
437 break;
438
439 __try {
440 if (NULL != thread_id &&
441 !ValidParameter(thread_id, sizeof(*thread_id), WRITE))
442 break;
443
444 if (nullptr == start_address)
445 break;
446 // We don't support thread_attributes not being null.
447 if (nullptr != thread_attributes)
448 break;
449 } __except (EXCEPTION_EXECUTE_HANDLER) {
450 break;
451 }
452
453 void* memory = GetGlobalIPCMemory();
454 if (nullptr == memory)
455 break;
456
457 SharedMemIPCClient ipc(memory);
458 CrossCallReturn answer = {0};
459
460 // NOTE: we don't pass the thread_attributes through. This matches the
461 // approach in CreateProcess and in CreateThreadInternal().
462 ResultCode code = CrossCall(ipc, IPC_CREATETHREAD_TAG,
463 reinterpret_cast<LPVOID>(stack_size),
464 reinterpret_cast<LPVOID>(start_address),
465 parameter, creation_flags, &answer);
466 if (SBOX_ALL_OK != code)
467 break;
468
469 ::SetLastError(answer.win32_result);
470 if (ERROR_SUCCESS != answer.win32_result) {
471 return NULL;
472 }
473
474 __try {
475 if (thread_id != NULL) {
476 *thread_id = ::GetThreadId(answer.handle);
477 }
478 return answer.handle;
479 } __except (EXCEPTION_EXECUTE_HANDLER) {
480 break;
481 }
482 } while (false);
483
484 ::SetLastError(original_error);
485 return NULL;
486 }
487
488 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/process_thread_interception.h ('k') | sandbox/win/src/process_thread_policy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698