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