OLD | NEW |
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/target_process.h" | 5 #include "sandbox/win/src/target_process.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <memory> | 10 #include <memory> |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 PIMAGE_NT_HEADERS nt_header = pe.GetNTHeaders(); | 65 PIMAGE_NT_HEADERS nt_header = pe.GetNTHeaders(); |
66 char* base = reinterpret_cast<char*>(entry_point) - | 66 char* base = reinterpret_cast<char*>(entry_point) - |
67 nt_header->OptionalHeader.AddressOfEntryPoint; | 67 nt_header->OptionalHeader.AddressOfEntryPoint; |
68 | 68 |
69 ::FreeLibrary(exe); | 69 ::FreeLibrary(exe); |
70 return base; | 70 return base; |
71 } | 71 } |
72 | 72 |
73 TargetProcess::TargetProcess(base::win::ScopedHandle initial_token, | 73 TargetProcess::TargetProcess(base::win::ScopedHandle initial_token, |
74 base::win::ScopedHandle lockdown_token, | 74 base::win::ScopedHandle lockdown_token, |
75 base::win::ScopedHandle lowbox_token, | |
76 HANDLE job, | 75 HANDLE job, |
77 ThreadProvider* thread_pool) | 76 ThreadProvider* thread_pool) |
78 // This object owns everything initialized here except thread_pool and | 77 // This object owns everything initialized here except thread_pool and |
79 // the job_ handle. The Job handle is closed by BrokerServices and results | 78 // the job_ handle. The Job handle is closed by BrokerServices and results |
80 // eventually in a call to our dtor. | 79 // eventually in a call to our dtor. |
81 : lockdown_token_(std::move(lockdown_token)), | 80 : lockdown_token_(std::move(lockdown_token)), |
82 initial_token_(std::move(initial_token)), | 81 initial_token_(std::move(initial_token)), |
83 lowbox_token_(std::move(lowbox_token)), | |
84 job_(job), | 82 job_(job), |
85 thread_pool_(thread_pool), | 83 thread_pool_(thread_pool), |
86 base_address_(NULL) {} | 84 base_address_(NULL) {} |
87 | 85 |
88 TargetProcess::~TargetProcess() { | 86 TargetProcess::~TargetProcess() { |
89 DWORD exit_code = 0; | 87 DWORD exit_code = 0; |
90 // Give a chance to the process to die. In most cases the JOB_KILL_ON_CLOSE | 88 // Give a chance to the process to die. In most cases the JOB_KILL_ON_CLOSE |
91 // will take effect only when the context changes. As far as the testing went, | 89 // will take effect only when the context changes. As far as the testing went, |
92 // this wait was enough to switch context and kill the processes in the job. | 90 // this wait was enough to switch context and kill the processes in the job. |
93 // If this process is already dead, the function will return without waiting. | 91 // If this process is already dead, the function will return without waiting. |
(...skipping 25 matching lines...) Expand all Loading... |
119 | 117 |
120 // Creates the target (child) process suspended and assigns it to the job | 118 // Creates the target (child) process suspended and assigns it to the job |
121 // object. | 119 // object. |
122 ResultCode TargetProcess::Create( | 120 ResultCode TargetProcess::Create( |
123 const wchar_t* exe_path, | 121 const wchar_t* exe_path, |
124 const wchar_t* command_line, | 122 const wchar_t* command_line, |
125 bool inherit_handles, | 123 bool inherit_handles, |
126 const base::win::StartupInformation& startup_info, | 124 const base::win::StartupInformation& startup_info, |
127 base::win::ScopedProcessInformation* target_info, | 125 base::win::ScopedProcessInformation* target_info, |
128 DWORD* win_error) { | 126 DWORD* win_error) { |
129 if (lowbox_token_.IsValid() && | |
130 base::win::GetVersion() < base::win::VERSION_WIN8) { | |
131 // We don't allow lowbox_token below Windows 8. | |
132 return SBOX_ERROR_BAD_PARAMS; | |
133 } | |
134 | |
135 exe_name_.reset(_wcsdup(exe_path)); | 127 exe_name_.reset(_wcsdup(exe_path)); |
136 | 128 |
137 // the command line needs to be writable by CreateProcess(). | 129 // the command line needs to be writable by CreateProcess(). |
138 std::unique_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(command_line)); | 130 std::unique_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(command_line)); |
139 | 131 |
140 // Start the target process suspended. | 132 // Start the target process suspended. |
141 DWORD flags = | 133 DWORD flags = |
142 CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS; | 134 CREATE_SUSPENDED | CREATE_UNICODE_ENVIRONMENT | DETACHED_PROCESS; |
143 | 135 |
144 if (startup_info.has_extended_startup_info()) | 136 if (startup_info.has_extended_startup_info()) |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 void* entry_point = reinterpret_cast<void*>(context.Eax); | 197 void* entry_point = reinterpret_cast<void*>(context.Eax); |
206 #pragma warning(pop) | 198 #pragma warning(pop) |
207 #endif // _WIN64 | 199 #endif // _WIN64 |
208 | 200 |
209 if (!target_info->DuplicateFrom(process_info)) { | 201 if (!target_info->DuplicateFrom(process_info)) { |
210 *win_error = ::GetLastError(); // This may or may not be correct. | 202 *win_error = ::GetLastError(); // This may or may not be correct. |
211 ::TerminateProcess(process_info.process_handle(), 0); | 203 ::TerminateProcess(process_info.process_handle(), 0); |
212 return SBOX_ERROR_DUPLICATE_TARGET_INFO; | 204 return SBOX_ERROR_DUPLICATE_TARGET_INFO; |
213 } | 205 } |
214 | 206 |
215 if (lowbox_token_.IsValid()) { | |
216 PROCESS_ACCESS_TOKEN process_access_token; | |
217 process_access_token.thread = process_info.thread_handle(); | |
218 process_access_token.token = lowbox_token_.Get(); | |
219 | |
220 NtSetInformationProcess SetInformationProcess = NULL; | |
221 ResolveNTFunctionPtr("NtSetInformationProcess", &SetInformationProcess); | |
222 | |
223 NTSTATUS status = SetInformationProcess( | |
224 process_info.process_handle(), | |
225 static_cast<PROCESS_INFORMATION_CLASS>(NtProcessInformationAccessToken), | |
226 &process_access_token, sizeof(process_access_token)); | |
227 if (!NT_SUCCESS(status)) { | |
228 *win_error = GetLastErrorFromNtStatus(status); | |
229 ::TerminateProcess(process_info.process_handle(), 0); // exit code | |
230 return SBOX_ERROR_SET_LOW_BOX_TOKEN; | |
231 } | |
232 } | |
233 | |
234 base_address_ = GetBaseAddress(exe_path, entry_point); | 207 base_address_ = GetBaseAddress(exe_path, entry_point); |
235 sandbox_process_info_.Set(process_info.Take()); | 208 sandbox_process_info_.Set(process_info.Take()); |
236 return SBOX_ALL_OK; | 209 return SBOX_ALL_OK; |
237 } | 210 } |
238 | 211 |
239 ResultCode TargetProcess::TransferVariable(const char* name, void* address, | 212 ResultCode TargetProcess::TransferVariable(const char* name, void* address, |
240 size_t size) { | 213 size_t size) { |
241 if (!sandbox_process_info_.IsValid()) | 214 if (!sandbox_process_info_.IsValid()) |
242 return SBOX_ERROR_UNEXPECTED_CALL; | 215 return SBOX_ERROR_UNEXPECTED_CALL; |
243 | 216 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 return SBOX_ALL_OK; | 328 return SBOX_ALL_OK; |
356 } | 329 } |
357 | 330 |
358 void TargetProcess::Terminate() { | 331 void TargetProcess::Terminate() { |
359 if (!sandbox_process_info_.IsValid()) | 332 if (!sandbox_process_info_.IsValid()) |
360 return; | 333 return; |
361 | 334 |
362 ::TerminateProcess(sandbox_process_info_.process_handle(), 0); | 335 ::TerminateProcess(sandbox_process_info_.process_handle(), 0); |
363 } | 336 } |
364 | 337 |
| 338 ResultCode TargetProcess::AssignLowBoxToken( |
| 339 const base::win::ScopedHandle& token) { |
| 340 if (!token.IsValid()) |
| 341 return SBOX_ALL_OK; |
| 342 PROCESS_ACCESS_TOKEN process_access_token = {}; |
| 343 process_access_token.token = token.Get(); |
| 344 |
| 345 NtSetInformationProcess SetInformationProcess = NULL; |
| 346 ResolveNTFunctionPtr("NtSetInformationProcess", &SetInformationProcess); |
| 347 |
| 348 NTSTATUS status = SetInformationProcess( |
| 349 sandbox_process_info_.process_handle(), |
| 350 static_cast<PROCESS_INFORMATION_CLASS>(NtProcessInformationAccessToken), |
| 351 &process_access_token, sizeof(process_access_token)); |
| 352 if (!NT_SUCCESS(status)) { |
| 353 ::SetLastError(GetLastErrorFromNtStatus(status)); |
| 354 return SBOX_ERROR_SET_LOW_BOX_TOKEN; |
| 355 } |
| 356 return SBOX_ALL_OK; |
| 357 } |
| 358 |
365 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { | 359 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { |
366 TargetProcess* target = | 360 TargetProcess* target = new TargetProcess( |
367 new TargetProcess(base::win::ScopedHandle(), base::win::ScopedHandle(), | 361 base::win::ScopedHandle(), base::win::ScopedHandle(), NULL, NULL); |
368 base::win::ScopedHandle(), NULL, NULL); | |
369 PROCESS_INFORMATION process_info = {}; | 362 PROCESS_INFORMATION process_info = {}; |
370 process_info.hProcess = process; | 363 process_info.hProcess = process; |
371 target->sandbox_process_info_.Set(process_info); | 364 target->sandbox_process_info_.Set(process_info); |
372 target->base_address_ = base_address; | 365 target->base_address_ = base_address; |
373 return target; | 366 return target; |
374 } | 367 } |
375 | 368 |
376 } // namespace sandbox | 369 } // namespace sandbox |
OLD | NEW |