Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Side by Side Diff: sandbox/win/src/broker_services.cc

Issue 1460903002: Unify PolicyBase into TargetPolicy. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@policy_dispatcher
Patch Set: Rebase. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/broker_services.h" 5 #include "sandbox/win/src/broker_services.h"
6 6
7 #include <AclAPI.h> 7 #include <AclAPI.h>
8 #include <vector>
8 9
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "base/macros.h" 11 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
12 #include "base/stl_util.h" 13 #include "base/stl_util.h"
13 #include "base/threading/platform_thread.h" 14 #include "base/threading/platform_thread.h"
14 #include "base/win/scoped_handle.h" 15 #include "base/win/scoped_handle.h"
15 #include "base/win/scoped_process_information.h" 16 #include "base/win/scoped_process_information.h"
16 #include "base/win/startup_information.h" 17 #include "base/win/startup_information.h"
17 #include "base/win/windows_version.h" 18 #include "base/win/windows_version.h"
18 #include "sandbox/win/src/app_container.h" 19 #include "sandbox/win/src/app_container.h"
19 #include "sandbox/win/src/process_mitigations.h" 20 #include "sandbox/win/src/process_mitigations.h"
20 #include "sandbox/win/src/sandbox_policy_base.h"
21 #include "sandbox/win/src/sandbox.h" 21 #include "sandbox/win/src/sandbox.h"
22 #include "sandbox/win/src/sandbox_policy.h"
22 #include "sandbox/win/src/target_process.h" 23 #include "sandbox/win/src/target_process.h"
23 #include "sandbox/win/src/win2k_threadpool.h" 24 #include "sandbox/win/src/win2k_threadpool.h"
24 #include "sandbox/win/src/win_utils.h" 25 #include "sandbox/win/src/win_utils.h"
25 26
26 namespace { 27 namespace {
27 28
28 // Utility function to associate a completion port to a job object. 29 // Utility function to associate a completion port to a job object.
29 bool AssociateCompletionPort(HANDLE job, HANDLE port, void* key) { 30 bool AssociateCompletionPort(HANDLE job, HANDLE port, void* key) {
30 JOBOBJECT_ASSOCIATE_COMPLETION_PORT job_acp = { key, port }; 31 JOBOBJECT_ASSOCIATE_COMPLETION_PORT job_acp = { key, port };
31 return ::SetInformationJobObject(job, 32 return ::SetInformationJobObject(job,
(...skipping 18 matching lines...) Expand all
50 enum { 51 enum {
51 THREAD_CTRL_NONE, 52 THREAD_CTRL_NONE,
52 THREAD_CTRL_REMOVE_PEER, 53 THREAD_CTRL_REMOVE_PEER,
53 THREAD_CTRL_QUIT, 54 THREAD_CTRL_QUIT,
54 THREAD_CTRL_LAST, 55 THREAD_CTRL_LAST,
55 }; 56 };
56 57
57 // Helper structure that allows the Broker to associate a job notification 58 // Helper structure that allows the Broker to associate a job notification
58 // with a job object and with a policy. 59 // with a job object and with a policy.
59 struct JobTracker { 60 struct JobTracker {
60 JobTracker(base::win::ScopedHandle job, sandbox::PolicyBase* policy) 61 JobTracker(base::win::ScopedHandle job, sandbox::TargetPolicy* policy)
61 : job(job.Pass()), policy(policy) { 62 : job(job.Pass()), policy(policy) {
62 } 63 }
63 ~JobTracker() { 64 ~JobTracker() {
64 FreeResources(); 65 FreeResources();
65 } 66 }
66 67
67 // Releases the Job and notifies the associated Policy object to release its 68 // Releases the Job and notifies the associated Policy object to release its
68 // resources as well. 69 // resources as well.
69 void FreeResources(); 70 void FreeResources();
70 71
71 base::win::ScopedHandle job; 72 base::win::ScopedHandle job;
72 sandbox::PolicyBase* policy; 73 sandbox::TargetPolicy* policy;
73 }; 74 };
74 75
75 void JobTracker::FreeResources() { 76 void JobTracker::FreeResources() {
76 if (policy) { 77 if (policy) {
77 BOOL res = ::TerminateJobObject(job.Get(), sandbox::SBOX_ALL_OK); 78 BOOL res = ::TerminateJobObject(job.Get(), sandbox::SBOX_ALL_OK);
78 DCHECK(res); 79 DCHECK(res);
79 // Closing the job causes the target process to be destroyed so this needs 80 // Closing the job causes the target process to be destroyed so this needs
80 // to happen before calling OnJobEmpty(). 81 // to happen before calling OnJobEmpty().
81 HANDLE stale_job_handle = job.Get(); 82 HANDLE stale_job_handle = job.Get();
82 job.Close(); 83 job.Close();
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 // Cancel the wait events and delete remaining peer trackers. 168 // Cancel the wait events and delete remaining peer trackers.
168 for (PeerTrackerMap::iterator it = peer_map_.begin(); 169 for (PeerTrackerMap::iterator it = peer_map_.begin();
169 it != peer_map_.end(); ++it) { 170 it != peer_map_.end(); ++it) {
170 DeregisterPeerTracker(it->second); 171 DeregisterPeerTracker(it->second);
171 } 172 }
172 173
173 ::DeleteCriticalSection(&lock_); 174 ::DeleteCriticalSection(&lock_);
174 } 175 }
175 176
176 TargetPolicy* BrokerServicesBase::CreatePolicy() { 177 TargetPolicy* BrokerServicesBase::CreatePolicy() {
177 // If you change the type of the object being created here you must also 178 return new TargetPolicy;
178 // change the downcast to it in SpawnTarget().
179 return new PolicyBase;
180 } 179 }
181 180
182 // The worker thread stays in a loop waiting for asynchronous notifications 181 // The worker thread stays in a loop waiting for asynchronous notifications
183 // from the job objects. Right now we only care about knowing when the last 182 // from the job objects. Right now we only care about knowing when the last
184 // process on a job terminates, but in general this is the place to tell 183 // process on a job terminates, but in general this is the place to tell
185 // the policy about events. 184 // the policy about events.
186 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) { 185 DWORD WINAPI BrokerServicesBase::TargetEventsThread(PVOID param) {
187 if (NULL == param) 186 if (NULL == param)
188 return 1; 187 return 1;
189 188
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 296
298 // Even though the resources touched by SpawnTarget can be accessed in 297 // Even though the resources touched by SpawnTarget can be accessed in
299 // multiple threads, the method itself cannot be called from more than 298 // multiple threads, the method itself cannot be called from more than
300 // 1 thread. This is to protect the global variables used while setting up 299 // 1 thread. This is to protect the global variables used while setting up
301 // the child process. 300 // the child process.
302 static DWORD thread_id = ::GetCurrentThreadId(); 301 static DWORD thread_id = ::GetCurrentThreadId();
303 DCHECK(thread_id == ::GetCurrentThreadId()); 302 DCHECK(thread_id == ::GetCurrentThreadId());
304 303
305 AutoLock lock(&lock_); 304 AutoLock lock(&lock_);
306 305
307 // This downcast is safe as long as we control CreatePolicy() 306 if (policy->GetAppContainer() && policy->GetLowBoxSid())
308 PolicyBase* policy_base = static_cast<PolicyBase*>(policy);
309
310 if (policy_base->GetAppContainer() && policy_base->GetLowBoxSid())
311 return SBOX_ERROR_BAD_PARAMS; 307 return SBOX_ERROR_BAD_PARAMS;
312 308
313 // Construct the tokens and the job object that we are going to associate 309 // Construct the tokens and the job object that we are going to associate
314 // with the soon to be created target process. 310 // with the soon to be created target process.
315 base::win::ScopedHandle initial_token; 311 base::win::ScopedHandle initial_token;
316 base::win::ScopedHandle lockdown_token; 312 base::win::ScopedHandle lockdown_token;
317 base::win::ScopedHandle lowbox_token; 313 base::win::ScopedHandle lowbox_token;
318 ResultCode result = SBOX_ALL_OK; 314 ResultCode result = SBOX_ALL_OK;
319 315
320 result = 316 result = policy->MakeTokens(&initial_token, &lockdown_token, &lowbox_token);
321 policy_base->MakeTokens(&initial_token, &lockdown_token, &lowbox_token);
322 if (SBOX_ALL_OK != result) 317 if (SBOX_ALL_OK != result)
323 return result; 318 return result;
324 319
325 base::win::ScopedHandle job; 320 base::win::ScopedHandle job;
326 result = policy_base->MakeJobObject(&job); 321 result = policy->MakeJobObject(&job);
327 if (SBOX_ALL_OK != result) 322 if (SBOX_ALL_OK != result)
328 return result; 323 return result;
329 324
330 // Initialize the startup information from the policy. 325 // Initialize the startup information from the policy.
331 base::win::StartupInformation startup_info; 326 base::win::StartupInformation startup_info;
332 // The liftime of |mitigations| and |inherit_handle_list| have to be at least 327 // The liftime of |mitigations| and |inherit_handle_list| have to be at least
333 // as long as |startup_info| because |UpdateProcThreadAttribute| requires that 328 // as long as |startup_info| because |UpdateProcThreadAttribute| requires that
334 // its |lpValue| parameter persist until |DeleteProcThreadAttributeList| is 329 // its |lpValue| parameter persist until |DeleteProcThreadAttributeList| is
335 // called; StartupInformation's destructor makes such a call. 330 // called; StartupInformation's destructor makes such a call.
336 DWORD64 mitigations; 331 DWORD64 mitigations;
337 332
338 std::vector<HANDLE> inherited_handle_list; 333 std::vector<HANDLE> inherited_handle_list;
339 334
340 base::string16 desktop = policy_base->GetAlternateDesktop(); 335 base::string16 desktop = policy->GetAlternateDesktop();
341 if (!desktop.empty()) { 336 if (!desktop.empty()) {
342 startup_info.startup_info()->lpDesktop = 337 startup_info.startup_info()->lpDesktop =
343 const_cast<wchar_t*>(desktop.c_str()); 338 const_cast<wchar_t*>(desktop.c_str());
344 } 339 }
345 340
346 bool inherit_handles = false; 341 bool inherit_handles = false;
347 342
348 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { 343 if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
349 int attribute_count = 0; 344 int attribute_count = 0;
350 const AppContainerAttributes* app_container = 345 const AppContainerAttributes* app_container = policy->GetAppContainer();
351 policy_base->GetAppContainer();
352 if (app_container) 346 if (app_container)
353 ++attribute_count; 347 ++attribute_count;
354 348
355 size_t mitigations_size; 349 size_t mitigations_size;
356 ConvertProcessMitigationsToPolicy(policy->GetProcessMitigations(), 350 ConvertProcessMitigationsToPolicy(policy->GetProcessMitigations(),
357 &mitigations, &mitigations_size); 351 &mitigations, &mitigations_size);
358 if (mitigations) 352 if (mitigations)
359 ++attribute_count; 353 ++attribute_count;
360 354
361 HANDLE stdout_handle = policy_base->GetStdoutHandle(); 355 HANDLE stdout_handle = policy->GetStdoutHandle();
362 HANDLE stderr_handle = policy_base->GetStderrHandle(); 356 HANDLE stderr_handle = policy->GetStderrHandle();
363 357
364 if (stdout_handle != INVALID_HANDLE_VALUE) 358 if (stdout_handle != INVALID_HANDLE_VALUE)
365 inherited_handle_list.push_back(stdout_handle); 359 inherited_handle_list.push_back(stdout_handle);
366 360
367 // Handles in the list must be unique. 361 // Handles in the list must be unique.
368 if (stderr_handle != stdout_handle && stderr_handle != INVALID_HANDLE_VALUE) 362 if (stderr_handle != stdout_handle && stderr_handle != INVALID_HANDLE_VALUE)
369 inherited_handle_list.push_back(stderr_handle); 363 inherited_handle_list.push_back(stderr_handle);
370 364
371 const HandleList& policy_handle_list = policy_base->GetHandlesBeingShared(); 365 const HandleList& policy_handle_list = policy->GetHandlesBeingShared();
372 366
373 for (auto handle : policy_handle_list) 367 for (auto handle : policy_handle_list)
374 inherited_handle_list.push_back(handle->Get()); 368 inherited_handle_list.push_back(handle->Get());
375 369
376 if (inherited_handle_list.size()) 370 if (inherited_handle_list.size())
377 ++attribute_count; 371 ++attribute_count;
378 372
379 if (!startup_info.InitializeProcThreadAttributeList(attribute_count)) 373 if (!startup_info.InitializeProcThreadAttributeList(attribute_count))
380 return SBOX_ERROR_PROC_THREAD_ATTRIBUTES; 374 return SBOX_ERROR_PROC_THREAD_ATTRIBUTES;
381 375
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 // Create the TargetProces object and spawn the target suspended. Note that 412 // Create the TargetProces object and spawn the target suspended. Note that
419 // Brokerservices does not own the target object. It is owned by the Policy. 413 // Brokerservices does not own the target object. It is owned by the Policy.
420 base::win::ScopedProcessInformation process_info; 414 base::win::ScopedProcessInformation process_info;
421 TargetProcess* target = 415 TargetProcess* target =
422 new TargetProcess(initial_token.Pass(), lockdown_token.Pass(), 416 new TargetProcess(initial_token.Pass(), lockdown_token.Pass(),
423 lowbox_token.Pass(), job.Get(), thread_pool_); 417 lowbox_token.Pass(), job.Get(), thread_pool_);
424 418
425 DWORD win_result = target->Create(exe_path, command_line, inherit_handles, 419 DWORD win_result = target->Create(exe_path, command_line, inherit_handles,
426 startup_info, &process_info); 420 startup_info, &process_info);
427 421
428 policy_base->ClearSharedHandles(); 422 policy->ClearSharedHandles();
429 423
430 if (ERROR_SUCCESS != win_result) { 424 if (ERROR_SUCCESS != win_result) {
431 SpawnCleanup(target, win_result); 425 SpawnCleanup(target, win_result);
432 return SBOX_ERROR_CREATE_PROCESS; 426 return SBOX_ERROR_CREATE_PROCESS;
433 } 427 }
434 428
435 // Now the policy is the owner of the target. 429 // Now the policy is the owner of the target.
436 if (!policy_base->AddTarget(target)) { 430 if (!policy->AddTarget(target)) {
437 return SpawnCleanup(target, 0); 431 return SpawnCleanup(target, 0);
438 } 432 }
439 433
440 // We are going to keep a pointer to the policy because we'll call it when 434 // We are going to keep a pointer to the policy because we'll call it when
441 // the job object generates notifications using the completion port. 435 // the job object generates notifications using the completion port.
442 policy_base->AddRef(); 436 policy->AddRef();
443 if (job.IsValid()) { 437 if (job.IsValid()) {
444 scoped_ptr<JobTracker> tracker(new JobTracker(job.Pass(), policy_base)); 438 scoped_ptr<JobTracker> tracker(new JobTracker(job.Pass(), policy));
445 439
446 // There is no obvious recovery after failure here. Previous version with 440 // There is no obvious recovery after failure here. Previous version with
447 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639 441 // SpawnCleanup() caused deletion of TargetProcess twice. crbug.com/480639
448 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(), 442 CHECK(AssociateCompletionPort(tracker->job.Get(), job_port_.Get(),
449 tracker.get())); 443 tracker.get()));
450 444
451 // Save the tracker because in cleanup we might need to force closing 445 // Save the tracker because in cleanup we might need to force closing
452 // the Jobs. 446 // the Jobs.
453 tracker_list_.push_back(tracker.release()); 447 tracker_list_.push_back(tracker.release());
454 child_process_ids_.insert(process_info.process_id()); 448 child_process_ids_.insert(process_info.process_id());
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 return SBOX_ERROR_UNSUPPORTED; 534 return SBOX_ERROR_UNSUPPORTED;
541 535
542 base::string16 name = LookupAppContainer(sid); 536 base::string16 name = LookupAppContainer(sid);
543 if (name.empty()) 537 if (name.empty())
544 return SBOX_ERROR_INVALID_APP_CONTAINER; 538 return SBOX_ERROR_INVALID_APP_CONTAINER;
545 539
546 return DeleteAppContainer(sid); 540 return DeleteAppContainer(sid);
547 } 541 }
548 542
549 } // namespace sandbox 543 } // namespace sandbox
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698