Chromium Code Reviews| 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/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/win/pe_image.h" | 9 #include "base/win/pe_image.h" |
| 10 #include "base/win/startup_information.h" | 10 #include "base/win/startup_information.h" |
| 11 #include "base/win/windows_version.h" | 11 #include "base/win/windows_version.h" |
| 12 #include "sandbox/win/src/crosscall_server.h" | 12 #include "sandbox/win/src/crosscall_server.h" |
| 13 #include "sandbox/win/src/crosscall_client.h" | 13 #include "sandbox/win/src/crosscall_client.h" |
| 14 #include "sandbox/win/src/policy_low_level.h" | 14 #include "sandbox/win/src/policy_low_level.h" |
| 15 #include "sandbox/win/src/sandbox_types.h" | 15 #include "sandbox/win/src/sandbox_types.h" |
| 16 #include "sandbox/win/src/sharedmem_ipc_server.h" | 16 #include "sandbox/win/src/sharedmem_ipc_server.h" |
| 17 #include "sandbox/win/src/win_utils.h" | |
| 17 | 18 |
| 18 namespace { | 19 namespace { |
| 19 | 20 |
| 20 void CopyPolicyToTarget(const void* source, size_t size, void* dest) { | 21 void CopyPolicyToTarget(const void* source, size_t size, void* dest) { |
| 21 if (!source || !size) | 22 if (!source || !size) |
| 22 return; | 23 return; |
| 23 memcpy(dest, source, size); | 24 memcpy(dest, source, size); |
| 24 sandbox::PolicyGlobal* policy = | 25 sandbox::PolicyGlobal* policy = |
| 25 reinterpret_cast<sandbox::PolicyGlobal*>(dest); | 26 reinterpret_cast<sandbox::PolicyGlobal*>(dest); |
| 26 | 27 |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 if (startup_info.has_extended_startup_info()) | 128 if (startup_info.has_extended_startup_info()) |
| 128 flags |= EXTENDED_STARTUPINFO_PRESENT; | 129 flags |= EXTENDED_STARTUPINFO_PRESENT; |
| 129 | 130 |
| 130 if (job_ && base::win::GetVersion() < base::win::VERSION_WIN8) { | 131 if (job_ && base::win::GetVersion() < base::win::VERSION_WIN8) { |
| 131 // Windows 8 implements nested jobs, but for older systems we need to | 132 // Windows 8 implements nested jobs, but for older systems we need to |
| 132 // break out of any job we're in to enforce our restrictions. | 133 // break out of any job we're in to enforce our restrictions. |
| 133 flags |= CREATE_BREAKAWAY_FROM_JOB; | 134 flags |= CREATE_BREAKAWAY_FROM_JOB; |
| 134 } | 135 } |
| 135 | 136 |
| 136 PROCESS_INFORMATION temp_process_info = {}; | 137 PROCESS_INFORMATION temp_process_info = {}; |
| 137 if (!::CreateProcessAsUserW(lockdown_token_.Get(), | 138 if (base::win::GetVersion() < base::win::VERSION_WIN8) { |
| 138 exe_path, | 139 if (!::CreateProcessAsUserW(lockdown_token_.Get(), |
|
forshaw
2015/02/20 11:38:02
There was some discussion about doing this trick f
Shrikant Kelkar
2015/02/21 02:32:41
No, I haven't tested on other platforms. But to be
| |
| 139 cmd_line.get(), | 140 exe_path, |
| 140 NULL, // No security attribute. | 141 cmd_line.get(), |
| 141 NULL, // No thread attribute. | 142 NULL, // No security attribute. |
| 142 inherit_handles, | 143 NULL, // No thread attribute. |
| 143 flags, | 144 inherit_handles, |
| 144 NULL, // Use the environment of the caller. | 145 flags, |
| 145 NULL, // Use current directory of the caller. | 146 NULL, // Use the environment of the caller. |
| 146 startup_info.startup_info(), | 147 NULL, // Use current directory of the caller. |
| 147 &temp_process_info)) { | 148 startup_info.startup_info(), |
| 148 return ::GetLastError(); | 149 &temp_process_info)) { |
| 150 return ::GetLastError(); | |
| 151 } | |
| 152 lockdown_token_.Close(); | |
| 153 } else { | |
| 154 // For Windows 8 and above we will first create process with default token | |
|
rvargas (doing something else)
2015/02/21 01:01:22
nit: create the process with a default... later, a
Shrikant Kelkar
2015/02/21 02:32:41
Done.
| |
| 155 // and then replace it later after setting primary thread token. This is | |
| 156 // required for setting app container token along with impersonation one. | |
| 157 if (!::CreateProcess(exe_path, | |
| 158 cmd_line.get(), | |
| 159 NULL, // No security attribute. | |
| 160 NULL, // No thread attribute. | |
| 161 inherit_handles, | |
| 162 flags, | |
| 163 NULL, // Use the environment of the caller. | |
| 164 NULL, // Use current directory of the caller. | |
| 165 startup_info.startup_info(), | |
| 166 &temp_process_info)) { | |
| 167 return ::GetLastError(); | |
| 168 } | |
| 149 } | 169 } |
| 150 base::win::ScopedProcessInformation process_info(temp_process_info); | 170 base::win::ScopedProcessInformation process_info(temp_process_info); |
| 151 lockdown_token_.Close(); | |
| 152 | 171 |
| 153 DWORD win_result = ERROR_SUCCESS; | 172 DWORD win_result = ERROR_SUCCESS; |
| 154 | 173 |
| 155 if (job_) { | 174 if (job_) { |
| 156 // Assign the suspended target to the windows job object. | 175 // Assign the suspended target to the windows job object. |
| 157 if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { | 176 if (!::AssignProcessToJobObject(job_, process_info.process_handle())) { |
| 158 win_result = ::GetLastError(); | 177 win_result = ::GetLastError(); |
| 159 ::TerminateProcess(process_info.process_handle(), 0); | 178 ::TerminateProcess(process_info.process_handle(), 0); |
| 160 return win_result; | 179 return win_result; |
| 161 } | 180 } |
| 162 } | 181 } |
| 163 | 182 |
| 164 if (initial_token_.IsValid()) { | 183 if (initial_token_.IsValid()) { |
| 165 // Change the token of the main thread of the new process for the | 184 // Change the token of the main thread of the new process for the |
| 166 // impersonation token with more rights. This allows the target to start; | 185 // impersonation token with more rights. This allows the target to start; |
| 167 // otherwise it will crash too early for us to help. | 186 // otherwise it will crash too early for us to help. |
| 168 HANDLE temp_thread = process_info.thread_handle(); | 187 HANDLE temp_thread = process_info.thread_handle(); |
| 169 if (!::SetThreadToken(&temp_thread, initial_token_.Get())) { | 188 if (!::SetThreadToken(&temp_thread, initial_token_.Get())) { |
| 170 win_result = ::GetLastError(); | 189 win_result = ::GetLastError(); |
| 171 // It might be a security breach if we let the target run outside the job | 190 // It might be a security breach if we let the target run outside the job |
| 172 // so kill it before it causes damage. | 191 // so kill it before it causes damage. |
| 173 ::TerminateProcess(process_info.process_handle(), 0); | 192 ::TerminateProcess(process_info.process_handle(), 0); |
| 174 return win_result; | 193 return win_result; |
| 175 } | 194 } |
| 176 initial_token_.Close(); | 195 initial_token_.Close(); |
| 177 } | 196 } |
| 178 | 197 |
| 198 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { | |
| 199 PROCESS_ACCESS_TOKEN process_access_token; | |
| 200 process_access_token.thread = process_info.thread_handle(); | |
| 201 process_access_token.token = lockdown_token_.Get(); | |
| 202 | |
| 203 NtSetInformationProcess SetInformationProcess = NULL; | |
| 204 ResolveNTFunctionPtr("NtSetInformationProcess", &SetInformationProcess); | |
| 205 | |
| 206 NTSTATUS status = SetInformationProcess( | |
| 207 process_info.process_handle(), | |
| 208 static_cast<PROCESS_INFORMATION_CLASS>(NtProcessInformationAccessToken), | |
| 209 &process_access_token, | |
| 210 sizeof(process_access_token)); | |
| 211 if (!NT_SUCCESS(status)) { | |
|
forshaw
2015/02/20 11:38:02
Missing a call to lockdown_token_.Close() for this
Will Harris
2015/02/21 01:13:15
This should get closed in TargetProcess descructor
rvargas (doing something else)
2015/02/21 01:26:01
Yes, not leaking. I thought that for some reason w
Shrikant Kelkar
2015/02/21 02:32:41
Done.
Shrikant Kelkar
2015/02/21 02:32:41
Done.
Shrikant Kelkar
2015/02/21 02:32:41
Done.
| |
| 212 win_result = ::GetLastError(); | |
| 213 ::TerminateProcess(process_info.process_handle(), 0); // exit code | |
| 214 return win_result; | |
| 215 } | |
| 216 } | |
| 217 | |
| 179 CONTEXT context; | 218 CONTEXT context; |
| 180 context.ContextFlags = CONTEXT_ALL; | 219 context.ContextFlags = CONTEXT_ALL; |
| 181 if (!::GetThreadContext(process_info.thread_handle(), &context)) { | 220 if (!::GetThreadContext(process_info.thread_handle(), &context)) { |
| 182 win_result = ::GetLastError(); | 221 win_result = ::GetLastError(); |
| 183 ::TerminateProcess(process_info.process_handle(), 0); | 222 ::TerminateProcess(process_info.process_handle(), 0); |
| 184 return win_result; | 223 return win_result; |
| 185 } | 224 } |
| 186 | 225 |
| 187 #if defined(_WIN64) | 226 #if defined(_WIN64) |
| 188 void* entry_point = reinterpret_cast<void*>(context.Rcx); | 227 void* entry_point = reinterpret_cast<void*>(context.Rcx); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { | 369 TargetProcess* MakeTestTargetProcess(HANDLE process, HMODULE base_address) { |
| 331 TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL); | 370 TargetProcess* target = new TargetProcess(NULL, NULL, NULL, NULL); |
| 332 PROCESS_INFORMATION process_info = {}; | 371 PROCESS_INFORMATION process_info = {}; |
| 333 process_info.hProcess = process; | 372 process_info.hProcess = process; |
| 334 target->sandbox_process_info_.Set(process_info); | 373 target->sandbox_process_info_.Set(process_info); |
| 335 target->base_address_ = base_address; | 374 target->base_address_ = base_address; |
| 336 return target; | 375 return target; |
| 337 } | 376 } |
| 338 | 377 |
| 339 } // namespace sandbox | 378 } // namespace sandbox |
| OLD | NEW |