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