| 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 |