OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 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/src/broker_services.h" | 5 #include "sandbox/src/broker_services.h" |
6 | 6 |
7 #include <AclAPI.h> | |
8 | |
9 #include "base/logging.h" | 7 #include "base/logging.h" |
10 #include "base/threading/platform_thread.h" | 8 #include "base/threading/platform_thread.h" |
11 #include "sandbox/src/sandbox_policy_base.h" | 9 #include "sandbox/src/sandbox_policy_base.h" |
12 #include "sandbox/src/sandbox.h" | 10 #include "sandbox/src/sandbox.h" |
13 #include "sandbox/src/target_process.h" | 11 #include "sandbox/src/target_process.h" |
14 #include "sandbox/src/win2k_threadpool.h" | 12 #include "sandbox/src/win2k_threadpool.h" |
15 #include "sandbox/src/win_utils.h" | 13 #include "sandbox/src/win_utils.h" |
16 | 14 |
17 namespace { | 15 namespace { |
18 | 16 |
(...skipping 18 matching lines...) Expand all Loading... |
37 } | 35 } |
38 | 36 |
39 // the different commands that you can send to the worker thread that | 37 // the different commands that you can send to the worker thread that |
40 // executes TargetEventsThread(). | 38 // executes TargetEventsThread(). |
41 enum { | 39 enum { |
42 THREAD_CTRL_NONE, | 40 THREAD_CTRL_NONE, |
43 THREAD_CTRL_QUIT, | 41 THREAD_CTRL_QUIT, |
44 THREAD_CTRL_LAST | 42 THREAD_CTRL_LAST |
45 }; | 43 }; |
46 | 44 |
47 // Adds deny ACEs to broker and returns the security descriptor so it can | |
48 // be applied to target processes. The returned descriptor must be freed by | |
49 // calling LocalFree. | |
50 PSECURITY_DESCRIPTOR SetSecurityDescriptorForBroker() { | |
51 static bool is_initialized = false; | |
52 DWORD error = ERROR_SUCCESS; | |
53 PSECURITY_DESCRIPTOR security_descriptor = NULL; | |
54 | |
55 if (!is_initialized) { | |
56 error = sandbox::SetObjectDenyRestrictedAndNull(GetCurrentProcess(), | |
57 SE_KERNEL_OBJECT); | |
58 if (error) { | |
59 ::SetLastError(error); | |
60 return NULL; | |
61 } | |
62 | |
63 is_initialized = true; | |
64 } | |
65 | |
66 // Save off resulting security descriptor for spawning the targets. | |
67 error = ::GetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, | |
68 DACL_SECURITY_INFORMATION, NULL, NULL, | |
69 NULL, NULL, &security_descriptor); | |
70 if (error) { | |
71 ::SetLastError(error); | |
72 return NULL; | |
73 } | |
74 | |
75 return security_descriptor; | |
76 } | |
77 | |
78 } | 45 } |
79 | 46 |
80 namespace sandbox { | 47 namespace sandbox { |
81 | 48 |
82 BrokerServicesBase::BrokerServicesBase() | 49 BrokerServicesBase::BrokerServicesBase() |
83 : thread_pool_(NULL), job_port_(NULL), no_targets_(NULL), | 50 : thread_pool_(NULL), job_port_(NULL), no_targets_(NULL), |
84 security_descriptor_(NULL), job_thread_(NULL) { | 51 job_thread_(NULL) { |
85 } | 52 } |
86 | 53 |
87 // The broker uses a dedicated worker thread that services the job completion | 54 // The broker uses a dedicated worker thread that services the job completion |
88 // port to perform policy notifications and associated cleanup tasks. | 55 // port to perform policy notifications and associated cleanup tasks. |
89 ResultCode BrokerServicesBase::Init() { | 56 ResultCode BrokerServicesBase::Init() { |
90 if ((NULL != job_port_) || (NULL != thread_pool_) || | 57 if ((NULL != job_port_) || (NULL != thread_pool_)) |
91 (NULL != security_descriptor_)) { | |
92 return SBOX_ERROR_UNEXPECTED_CALL; | 58 return SBOX_ERROR_UNEXPECTED_CALL; |
93 } | |
94 | 59 |
95 ::InitializeCriticalSection(&lock_); | 60 ::InitializeCriticalSection(&lock_); |
96 | 61 |
97 job_port_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); | 62 job_port_ = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); |
98 if (NULL == job_port_) | 63 if (NULL == job_port_) |
99 return SBOX_ERROR_GENERIC; | 64 return SBOX_ERROR_GENERIC; |
100 | 65 |
101 security_descriptor_ = SetSecurityDescriptorForBroker(); | |
102 if (NULL == security_descriptor_) | |
103 return SBOX_ERROR_GENERIC; | |
104 | |
105 no_targets_ = ::CreateEventW(NULL, TRUE, FALSE, NULL); | 66 no_targets_ = ::CreateEventW(NULL, TRUE, FALSE, NULL); |
106 | 67 |
107 job_thread_ = ::CreateThread(NULL, 0, // Default security and stack. | 68 job_thread_ = ::CreateThread(NULL, 0, // Default security and stack. |
108 TargetEventsThread, this, NULL, NULL); | 69 TargetEventsThread, this, NULL, NULL); |
109 if (NULL == job_thread_) | 70 if (NULL == job_thread_) |
110 return SBOX_ERROR_GENERIC; | 71 return SBOX_ERROR_GENERIC; |
111 | 72 |
112 return SBOX_ALL_OK; | 73 return SBOX_ALL_OK; |
113 } | 74 } |
114 | 75 |
(...skipping 21 matching lines...) Expand all Loading... |
136 | 97 |
137 JobTrackerList::iterator it; | 98 JobTrackerList::iterator it; |
138 for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) { | 99 for (it = tracker_list_.begin(); it != tracker_list_.end(); ++it) { |
139 JobTracker* tracker = (*it); | 100 JobTracker* tracker = (*it); |
140 FreeResources(tracker); | 101 FreeResources(tracker); |
141 delete tracker; | 102 delete tracker; |
142 } | 103 } |
143 ::CloseHandle(job_thread_); | 104 ::CloseHandle(job_thread_); |
144 delete thread_pool_; | 105 delete thread_pool_; |
145 ::CloseHandle(no_targets_); | 106 ::CloseHandle(no_targets_); |
146 | |
147 if (security_descriptor_) | |
148 ::LocalFree(security_descriptor_); | |
149 | |
150 // If job_port_ isn't NULL, assumes that the lock has been initialized. | 107 // If job_port_ isn't NULL, assumes that the lock has been initialized. |
151 if (job_port_) | 108 if (job_port_) |
152 ::DeleteCriticalSection(&lock_); | 109 ::DeleteCriticalSection(&lock_); |
153 } | 110 } |
154 | 111 |
155 TargetPolicy* BrokerServicesBase::CreatePolicy() { | 112 TargetPolicy* BrokerServicesBase::CreatePolicy() { |
156 // If you change the type of the object being created here you must also | 113 // If you change the type of the object being created here you must also |
157 // change the downcast to it in SpawnTarget(). | 114 // change the downcast to it in SpawnTarget(). |
158 return new PolicyBase; | 115 return new PolicyBase; |
159 } | 116 } |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 return SBOX_ERROR_GENERIC; | 256 return SBOX_ERROR_GENERIC; |
300 | 257 |
301 // Construct the thread pool here in case it is expensive. | 258 // Construct the thread pool here in case it is expensive. |
302 // The thread pool is shared by all the targets | 259 // The thread pool is shared by all the targets |
303 if (NULL == thread_pool_) | 260 if (NULL == thread_pool_) |
304 thread_pool_ = new Win2kThreadPool(); | 261 thread_pool_ = new Win2kThreadPool(); |
305 | 262 |
306 // Create the TargetProces object and spawn the target suspended. Note that | 263 // Create the TargetProces object and spawn the target suspended. Note that |
307 // Brokerservices does not own the target object. It is owned by the Policy. | 264 // Brokerservices does not own the target object. It is owned by the Policy. |
308 PROCESS_INFORMATION process_info = {0}; | 265 PROCESS_INFORMATION process_info = {0}; |
309 | |
310 TargetProcess* target = new TargetProcess(initial_token, lockdown_token, | 266 TargetProcess* target = new TargetProcess(initial_token, lockdown_token, |
311 job, thread_pool_); | 267 job, thread_pool_); |
312 | 268 |
313 std::wstring desktop = policy_base->GetAlternateDesktop(); | 269 std::wstring desktop = policy_base->GetAlternateDesktop(); |
314 | 270 |
315 // Set the security descriptor so the target picks up deny ACEs. | |
316 SECURITY_ATTRIBUTES security_attributes = {sizeof(security_attributes), | |
317 security_descriptor_, | |
318 FALSE}; | |
319 | |
320 win_result = target->Create(exe_path, command_line, | 271 win_result = target->Create(exe_path, command_line, |
321 desktop.empty() ? NULL : desktop.c_str(), | 272 desktop.empty() ? NULL : desktop.c_str(), |
322 &security_attributes, | |
323 &process_info); | 273 &process_info); |
324 if (ERROR_SUCCESS != win_result) | 274 if (ERROR_SUCCESS != win_result) |
325 return SpawnCleanup(target, win_result); | 275 return SpawnCleanup(target, win_result); |
326 | 276 |
327 if ((INVALID_HANDLE_VALUE == process_info.hProcess) || | 277 if ((INVALID_HANDLE_VALUE == process_info.hProcess) || |
328 (INVALID_HANDLE_VALUE == process_info.hThread)) | 278 (INVALID_HANDLE_VALUE == process_info.hThread)) |
329 return SpawnCleanup(target, win_result); | 279 return SpawnCleanup(target, win_result); |
330 | 280 |
331 // Now the policy is the owner of the target. | 281 // Now the policy is the owner of the target. |
332 if (!policy_base->AddTarget(target)) { | 282 if (!policy_base->AddTarget(target)) { |
(...skipping 23 matching lines...) Expand all Loading... |
356 return SBOX_ALL_OK; | 306 return SBOX_ALL_OK; |
357 } | 307 } |
358 | 308 |
359 | 309 |
360 ResultCode BrokerServicesBase::WaitForAllTargets() { | 310 ResultCode BrokerServicesBase::WaitForAllTargets() { |
361 ::WaitForSingleObject(no_targets_, INFINITE); | 311 ::WaitForSingleObject(no_targets_, INFINITE); |
362 return SBOX_ALL_OK; | 312 return SBOX_ALL_OK; |
363 } | 313 } |
364 | 314 |
365 } // namespace sandbox | 315 } // namespace sandbox |
OLD | NEW |