Chromium Code Reviews| Index: sandbox/win/src/target_process.cc |
| diff --git a/sandbox/win/src/target_process.cc b/sandbox/win/src/target_process.cc |
| index 2c5bf3b1f9736975baa9cadf3a558c01873a9c3a..f401562d239d42d8dc65a2b25a8a6993bdb830d3 100644 |
| --- a/sandbox/win/src/target_process.cc |
| +++ b/sandbox/win/src/target_process.cc |
| @@ -14,6 +14,7 @@ |
| #include "sandbox/win/src/policy_low_level.h" |
| #include "sandbox/win/src/sandbox_types.h" |
| #include "sandbox/win/src/sharedmem_ipc_server.h" |
| +#include "sandbox/win/src/win_utils.h" |
| namespace { |
| @@ -113,8 +114,15 @@ TargetProcess::~TargetProcess() { |
| DWORD TargetProcess::Create(const wchar_t* exe_path, |
| const wchar_t* command_line, |
| bool inherit_handles, |
| + bool set_lockdown_token_after_create, |
| const base::win::StartupInformation& startup_info, |
| base::win::ScopedProcessInformation* target_info) { |
| + if (set_lockdown_token_after_create && |
| + base::win::GetVersion() < base::win::VERSION_WIN8) { |
| + // We don't allow set_lockdown_token_after_create below Windows 8. |
| + return ERROR_INVALID_PARAMETER; |
| + } |
| + |
| exe_name_.reset(_wcsdup(exe_path)); |
| // the command line needs to be writable by CreateProcess(). |
| @@ -133,22 +141,40 @@ DWORD TargetProcess::Create(const wchar_t* exe_path, |
| flags |= CREATE_BREAKAWAY_FROM_JOB; |
| } |
| + base::win::ScopedHandle scoped_lockdown_token(lockdown_token_.Take()); |
| PROCESS_INFORMATION temp_process_info = {}; |
| - if (!::CreateProcessAsUserW(lockdown_token_.Get(), |
| - exe_path, |
| - cmd_line.get(), |
| - NULL, // No security attribute. |
| - NULL, // No thread attribute. |
| - inherit_handles, |
| - flags, |
| - NULL, // Use the environment of the caller. |
| - NULL, // Use current directory of the caller. |
| - startup_info.startup_info(), |
| - &temp_process_info)) { |
| - return ::GetLastError(); |
| + if (!set_lockdown_token_after_create) { |
|
rvargas (doing something else)
2015/02/28 01:10:06
nit: if (set_lockdown_token_after_create)
Shrikant Kelkar
2015/02/28 01:55:42
Done.
|
| + if (!::CreateProcessAsUserW(scoped_lockdown_token.Get(), |
| + exe_path, |
| + cmd_line.get(), |
| + NULL, // No security attribute. |
| + NULL, // No thread attribute. |
| + inherit_handles, |
| + flags, |
| + NULL, // Use the environment of the caller. |
| + NULL, // Use current directory of the caller. |
| + startup_info.startup_info(), |
| + &temp_process_info)) { |
| + return ::GetLastError(); |
| + } |
| + } else { |
| + // Our approach is to first create process with a default token and then |
|
rvargas (doing something else)
2015/02/28 01:10:07
nit: remove "our approach"
Shrikant Kelkar
2015/02/28 01:55:42
Done.
|
| + // replace it later, after setting primary thread token. This is required |
| + // for setting an appcontainer token along with an impersonation token. |
|
rvargas (doing something else)
2015/02/28 01:10:06
nit: AppContainer
Shrikant Kelkar
2015/02/28 01:55:42
Done.
|
| + if (!::CreateProcess(exe_path, |
| + cmd_line.get(), |
| + NULL, // No security attribute. |
| + NULL, // No thread attribute. |
| + inherit_handles, |
| + flags, |
| + NULL, // Use the environment of the caller. |
| + NULL, // Use current directory of the caller. |
| + startup_info.startup_info(), |
| + &temp_process_info)) { |
| + return ::GetLastError(); |
| + } |
| } |
| base::win::ScopedProcessInformation process_info(temp_process_info); |
| - lockdown_token_.Close(); |
| DWORD win_result = ERROR_SUCCESS; |
| @@ -176,6 +202,26 @@ DWORD TargetProcess::Create(const wchar_t* exe_path, |
| initial_token_.Close(); |
| } |
| + if (set_lockdown_token_after_create) { |
| + PROCESS_ACCESS_TOKEN process_access_token; |
| + process_access_token.thread = process_info.thread_handle(); |
| + process_access_token.token = scoped_lockdown_token.Get(); |
| + |
| + NtSetInformationProcess SetInformationProcess = NULL; |
| + ResolveNTFunctionPtr("NtSetInformationProcess", &SetInformationProcess); |
| + |
| + NTSTATUS status = SetInformationProcess( |
| + process_info.process_handle(), |
| + static_cast<PROCESS_INFORMATION_CLASS>(NtProcessInformationAccessToken), |
| + &process_access_token, |
| + sizeof(process_access_token)); |
| + if (!NT_SUCCESS(status)) { |
| + win_result = ::GetLastError(); |
| + ::TerminateProcess(process_info.process_handle(), 0); // exit code |
| + return win_result; |
| + } |
| + } |
| + |
| CONTEXT context; |
| context.ContextFlags = CONTEXT_ALL; |
| if (!::GetThreadContext(process_info.thread_handle(), &context)) { |