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 |