| 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 "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/debug/alias.h" |
| 9 #include "base/debug/dump_without_crashing.h" |
| 8 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/win/pe_image.h" | 11 #include "base/win/pe_image.h" |
| 10 #include "base/win/startup_information.h" | 12 #include "base/win/startup_information.h" |
| 11 #include "base/win/windows_version.h" | 13 #include "base/win/windows_version.h" |
| 12 #include "sandbox/win/src/crosscall_server.h" | 14 #include "sandbox/win/src/crosscall_server.h" |
| 13 #include "sandbox/win/src/crosscall_client.h" | 15 #include "sandbox/win/src/crosscall_client.h" |
| 14 #include "sandbox/win/src/policy_low_level.h" | 16 #include "sandbox/win/src/policy_low_level.h" |
| 15 #include "sandbox/win/src/sandbox_types.h" | 17 #include "sandbox/win/src/sandbox_types.h" |
| 16 #include "sandbox/win/src/sharedmem_ipc_server.h" | 18 #include "sandbox/win/src/sharedmem_ipc_server.h" |
| 17 #include "sandbox/win/src/win_utils.h" | 19 #include "sandbox/win/src/win_utils.h" |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 if (!::CreateProcess(exe_path, | 152 if (!::CreateProcess(exe_path, |
| 151 cmd_line.get(), | 153 cmd_line.get(), |
| 152 NULL, // No security attribute. | 154 NULL, // No security attribute. |
| 153 NULL, // No thread attribute. | 155 NULL, // No thread attribute. |
| 154 inherit_handles, | 156 inherit_handles, |
| 155 flags, | 157 flags, |
| 156 NULL, // Use the environment of the caller. | 158 NULL, // Use the environment of the caller. |
| 157 NULL, // Use current directory of the caller. | 159 NULL, // Use current directory of the caller. |
| 158 startup_info.startup_info(), | 160 startup_info.startup_info(), |
| 159 &temp_process_info)) { | 161 &temp_process_info)) { |
| 162 // TODO(shrikant): Remove following code once we gather some dumps for |
| 163 // debugging appcontainer related failures (crbug.com/467920). |
| 164 base::debug::Alias(exe_path); |
| 165 base::debug::DumpWithoutCrashing(); |
| 160 return ::GetLastError(); | 166 return ::GetLastError(); |
| 161 } | 167 } |
| 162 } else { | 168 } else { |
| 163 if (!::CreateProcessAsUserW(scoped_lockdown_token.Get(), | 169 if (!::CreateProcessAsUserW(scoped_lockdown_token.Get(), |
| 164 exe_path, | 170 exe_path, |
| 165 cmd_line.get(), | 171 cmd_line.get(), |
| 166 NULL, // No security attribute. | 172 NULL, // No security attribute. |
| 167 NULL, // No thread attribute. | 173 NULL, // No thread attribute. |
| 168 inherit_handles, | 174 inherit_handles, |
| 169 flags, | 175 flags, |
| 170 NULL, // Use the environment of the caller. | 176 NULL, // Use the environment of the caller. |
| 171 NULL, // Use current directory of the caller. | 177 NULL, // Use current directory of the caller. |
| 172 startup_info.startup_info(), | 178 startup_info.startup_info(), |
| 173 &temp_process_info)) { | 179 &temp_process_info)) { |
| 174 return ::GetLastError(); | 180 return ::GetLastError(); |
| 175 } | 181 } |
| 176 } | 182 } |
| 177 base::win::ScopedProcessInformation process_info(temp_process_info); | 183 base::win::ScopedProcessInformation process_info(temp_process_info); |
| 178 | 184 |
| 179 DWORD win_result = ERROR_SUCCESS; | 185 DWORD win_result = ERROR_SUCCESS; |
| 180 | 186 |
| 181 if (job_) { | 187 if (job_) { |
| 182 // Assign the suspended target to the windows job object. | 188 // Assign the suspended target to the windows job object. |
| 183 if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { | 189 if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { |
| 184 win_result = ::GetLastError(); | 190 win_result = ::GetLastError(); |
| 191 if (set_lockdown_token_after_create) { |
| 192 // TODO(shrikant): Remove this code once we gather some dumps for |
| 193 // debugging appcontainer related failures (crbug.com/467920). |
| 194 base::debug::Alias(&win_result); |
| 195 base::debug::DumpWithoutCrashing(); |
| 196 } |
| 185 ::TerminateProcess(process_info.process_handle(), 0); | 197 ::TerminateProcess(process_info.process_handle(), 0); |
| 186 return win_result; | 198 return win_result; |
| 187 } | 199 } |
| 188 } | 200 } |
| 189 | 201 |
| 190 if (initial_token_.IsValid()) { | 202 if (initial_token_.IsValid()) { |
| 191 // Change the token of the main thread of the new process for the | 203 // Change the token of the main thread of the new process for the |
| 192 // impersonation token with more rights. This allows the target to start; | 204 // impersonation token with more rights. This allows the target to start; |
| 193 // otherwise it will crash too early for us to help. | 205 // otherwise it will crash too early for us to help. |
| 194 HANDLE temp_thread = process_info.thread_handle(); | 206 HANDLE temp_thread = process_info.thread_handle(); |
| 195 if (!::SetThreadToken(&temp_thread, initial_token_.Get())) { | 207 if (!::SetThreadToken(&temp_thread, initial_token_.Get())) { |
| 196 win_result = ::GetLastError(); | 208 win_result = ::GetLastError(); |
| 209 if (set_lockdown_token_after_create) { |
| 210 // TODO(shrikant): Remove this code once we gather some dumps for |
| 211 // debugging appcontainer related failures (crbug.com/467920). |
| 212 base::debug::Alias(&win_result); |
| 213 base::debug::DumpWithoutCrashing(); |
| 214 } |
| 197 // It might be a security breach if we let the target run outside the job | 215 // It might be a security breach if we let the target run outside the job |
| 198 // so kill it before it causes damage. | 216 // so kill it before it causes damage. |
| 199 ::TerminateProcess(process_info.process_handle(), 0); | 217 ::TerminateProcess(process_info.process_handle(), 0); |
| 200 return win_result; | 218 return win_result; |
| 201 } | 219 } |
| 202 initial_token_.Close(); | 220 initial_token_.Close(); |
| 203 } | 221 } |
| 204 | 222 |
| 205 if (set_lockdown_token_after_create) { | 223 if (set_lockdown_token_after_create) { |
| 206 PROCESS_ACCESS_TOKEN process_access_token; | 224 PROCESS_ACCESS_TOKEN process_access_token; |
| 207 process_access_token.thread = process_info.thread_handle(); | 225 process_access_token.thread = process_info.thread_handle(); |
| 208 process_access_token.token = scoped_lockdown_token.Get(); | 226 process_access_token.token = scoped_lockdown_token.Get(); |
| 209 | 227 |
| 210 NtSetInformationProcess SetInformationProcess = NULL; | 228 NtSetInformationProcess SetInformationProcess = NULL; |
| 211 ResolveNTFunctionPtr("NtSetInformationProcess", &SetInformationProcess); | 229 ResolveNTFunctionPtr("NtSetInformationProcess", &SetInformationProcess); |
| 212 | 230 |
| 213 NTSTATUS status = SetInformationProcess( | 231 NTSTATUS status = SetInformationProcess( |
| 214 process_info.process_handle(), | 232 process_info.process_handle(), |
| 215 static_cast<PROCESS_INFORMATION_CLASS>(NtProcessInformationAccessToken), | 233 static_cast<PROCESS_INFORMATION_CLASS>(NtProcessInformationAccessToken), |
| 216 &process_access_token, | 234 &process_access_token, |
| 217 sizeof(process_access_token)); | 235 sizeof(process_access_token)); |
| 218 if (!NT_SUCCESS(status)) { | 236 if (!NT_SUCCESS(status)) { |
| 219 win_result = ::GetLastError(); | 237 win_result = ::GetLastError(); |
| 238 // TODO(shrikant): Remove this code once we gather some dumps for |
| 239 // debugging appcontainer related failures (crbug.com/467920). |
| 240 base::debug::Alias(&win_result); |
| 241 base::debug::DumpWithoutCrashing(); |
| 220 ::TerminateProcess(process_info.process_handle(), 0); // exit code | 242 ::TerminateProcess(process_info.process_handle(), 0); // exit code |
| 221 return win_result; | 243 return win_result; |
| 222 } | 244 } |
| 223 } | 245 } |
| 224 | 246 |
| 225 CONTEXT context; | 247 CONTEXT context; |
| 226 context.ContextFlags = CONTEXT_ALL; | 248 context.ContextFlags = CONTEXT_ALL; |
| 227 if (!::GetThreadContext(process_info.thread_handle(), &context)) { | 249 if (!::GetThreadContext(process_info.thread_handle(), &context)) { |
| 228 win_result = ::GetLastError(); | 250 win_result = ::GetLastError(); |
| 251 if (set_lockdown_token_after_create) { |
| 252 // TODO(shrikant): Remove this code once we gather some dumps for |
| 253 // debugging appcontainer related failures (crbug.com/467920). |
| 254 base::debug::Alias(&win_result); |
| 255 base::debug::DumpWithoutCrashing(); |
| 256 } |
| 229 ::TerminateProcess(process_info.process_handle(), 0); | 257 ::TerminateProcess(process_info.process_handle(), 0); |
| 230 return win_result; | 258 return win_result; |
| 231 } | 259 } |
| 232 | 260 |
| 233 #if defined(_WIN64) | 261 #if defined(_WIN64) |
| 234 void* entry_point = reinterpret_cast<void*>(context.Rcx); | 262 void* entry_point = reinterpret_cast<void*>(context.Rcx); |
| 235 #else | 263 #else |
| 236 #pragma warning(push) | 264 #pragma warning(push) |
| 237 #pragma warning(disable: 4312) | 265 #pragma warning(disable: 4312) |
| 238 // This cast generates a warning because it is 32 bit specific. | 266 // This cast generates a warning because it is 32 bit specific. |
| 239 void* entry_point = reinterpret_cast<void*>(context.Eax); | 267 void* entry_point = reinterpret_cast<void*>(context.Eax); |
| 240 #pragma warning(pop) | 268 #pragma warning(pop) |
| 241 #endif // _WIN64 | 269 #endif // _WIN64 |
| 242 | 270 |
| 243 if (!target_info->DuplicateFrom(process_info)) { | 271 if (!target_info->DuplicateFrom(process_info)) { |
| 244 win_result = ::GetLastError(); // This may or may not be correct. | 272 win_result = ::GetLastError(); // This may or may not be correct. |
| 273 if (set_lockdown_token_after_create) { |
| 274 // TODO(shrikant): Remove this code once we gather some dumps for |
| 275 // debugging appcontainer related failures (crbug.com/467920). |
| 276 base::debug::Alias(&win_result); |
| 277 base::debug::DumpWithoutCrashing(); |
| 278 } |
| 245 ::TerminateProcess(process_info.process_handle(), 0); | 279 ::TerminateProcess(process_info.process_handle(), 0); |
| 246 return win_result; | 280 return win_result; |
| 247 } | 281 } |
| 248 | 282 |
| 249 base_address_ = GetBaseAddress(exe_path, entry_point); | 283 base_address_ = GetBaseAddress(exe_path, entry_point); |
| 250 sandbox_process_info_.Set(process_info.Take()); | 284 sandbox_process_info_.Set(process_info.Take()); |
| 251 return win_result; | 285 return win_result; |
| 252 } | 286 } |
| 253 | 287 |
| 254 ResultCode TargetProcess::TransferVariable(const char* name, void* address, | 288 ResultCode TargetProcess::TransferVariable(const char* name, void* address, |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { | 410 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { |
| 377 TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL); | 411 TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL); |
| 378 PROCESS_INFORMATION process_info = {}; | 412 PROCESS_INFORMATION process_info = {}; |
| 379 process_info.hProcess = process; | 413 process_info.hProcess = process; |
| 380 target->sandbox_process_info_.Set(process_info); | 414 target->sandbox_process_info_.Set(process_info); |
| 381 target->base_address_ = base_address; | 415 target->base_address_ = base_address; |
| 382 return target; | 416 return target; |
| 383 } | 417 } |
| 384 | 418 |
| 385 } // namespace sandbox | 419 } // namespace sandbox |
| OLD | NEW |