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

Side by Side Diff: sandbox/src/target_services.cc

Issue 10689170: Move the Windows sandbox to sandbox/win (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on top of tree (properly this time) Created 8 years, 5 months 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 | Annotate | Revision Log
« no previous file with comments | « sandbox/src/target_services.h ('k') | sandbox/src/threadpool_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "sandbox/src/target_services.h"
6
7 #include <process.h>
8
9 #include "base/basictypes.h"
10 #include "sandbox/src/crosscall_client.h"
11 #include "sandbox/src/handle_closer_agent.h"
12 #include "sandbox/src/handle_interception.h"
13 #include "sandbox/src/ipc_tags.h"
14 #include "sandbox/src/restricted_token_utils.h"
15 #include "sandbox/src/sandbox.h"
16 #include "sandbox/src/sandbox_types.h"
17 #include "sandbox/src/sharedmem_ipc_client.h"
18 #include "sandbox/src/sandbox_nt_util.h"
19
20 namespace {
21
22 // Flushing a cached key is triggered by just opening the key and closing the
23 // resulting handle. RegDisablePredefinedCache() is the documented way to flush
24 // HKCU so do not use it with this function.
25 bool FlushRegKey(HKEY root) {
26 HKEY key;
27 if (ERROR_SUCCESS == ::RegOpenKeyExW(root, NULL, 0, MAXIMUM_ALLOWED, &key)) {
28 if (ERROR_SUCCESS != ::RegCloseKey(key))
29 return false;
30 }
31 return true;
32 }
33
34 // This function forces advapi32.dll to release some internally cached handles
35 // that were made during calls to RegOpenkey and RegOpenKeyEx if it is called
36 // with a more restrictive token. Returns true if the flushing is succesful
37 // although this behavior is undocumented and there is no guarantee that in
38 // fact this will happen in future versions of windows.
39 bool FlushCachedRegHandles() {
40 return (FlushRegKey(HKEY_LOCAL_MACHINE) &&
41 FlushRegKey(HKEY_CLASSES_ROOT) &&
42 FlushRegKey(HKEY_USERS));
43 }
44
45 // Checks if we have handle entries pending and runs the closer.
46 bool CloseOpenHandles() {
47 if (sandbox::HandleCloserAgent::NeedsHandlesClosed()) {
48 sandbox::HandleCloserAgent handle_closer;
49
50 handle_closer.InitializeHandlesToClose();
51 if (!handle_closer.CloseHandles())
52 return false;
53 }
54
55 return true;
56 }
57
58 } // namespace
59
60 namespace sandbox {
61
62 SANDBOX_INTERCEPT IntegrityLevel g_shared_delayed_integrity_level =
63 INTEGRITY_LEVEL_LAST;
64
65 TargetServicesBase::TargetServicesBase() {
66 }
67
68 ResultCode TargetServicesBase::Init() {
69 process_state_.SetInitCalled();
70 return SBOX_ALL_OK;
71 }
72
73 // Failure here is a breach of security so the process is terminated.
74 void TargetServicesBase::LowerToken() {
75 if (ERROR_SUCCESS !=
76 SetProcessIntegrityLevel(g_shared_delayed_integrity_level))
77 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_INTEGRITY);
78 process_state_.SetRevertedToSelf();
79 // If the client code as called RegOpenKey, advapi32.dll has cached some
80 // handles. The following code gets rid of them.
81 if (!::RevertToSelf())
82 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_DROPTOKEN);
83 if (!FlushCachedRegHandles())
84 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_FLUSHANDLES);
85 if (ERROR_SUCCESS != ::RegDisablePredefinedCache())
86 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE);
87 if (!CloseOpenHandles())
88 ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES);
89 }
90
91 ProcessState* TargetServicesBase::GetState() {
92 return &process_state_;
93 }
94
95 TargetServicesBase* TargetServicesBase::GetInstance() {
96 static TargetServicesBase instance;
97 return &instance;
98 }
99
100 // The broker services a 'test' IPC service with the IPC_PING_TAG tag.
101 bool TargetServicesBase::TestIPCPing(int version) {
102 void* memory = GetGlobalIPCMemory();
103 if (NULL == memory) {
104 return false;
105 }
106 SharedMemIPCClient ipc(memory);
107 CrossCallReturn answer = {0};
108
109 if (1 == version) {
110 uint32 tick1 = ::GetTickCount();
111 uint32 cookie = 717115;
112 ResultCode code = CrossCall(ipc, IPC_PING1_TAG, cookie, &answer);
113
114 if (SBOX_ALL_OK != code) {
115 return false;
116 }
117 // We should get two extended returns values from the IPC, one is the
118 // tick count on the broker and the other is the cookie times two.
119 if ((answer.extended_count != 2)) {
120 return false;
121 }
122 // We test the first extended answer to be within the bounds of the tick
123 // count only if there was no tick count wraparound.
124 uint32 tick2 = ::GetTickCount();
125 if (tick2 >= tick1) {
126 if ((answer.extended[0].unsigned_int < tick1) ||
127 (answer.extended[0].unsigned_int > tick2)) {
128 return false;
129 }
130 }
131
132 if (answer.extended[1].unsigned_int != cookie * 2) {
133 return false;
134 }
135 } else if (2 == version) {
136 uint32 cookie = 717111;
137 InOutCountedBuffer counted_buffer(&cookie, sizeof(cookie));
138 ResultCode code = CrossCall(ipc, IPC_PING2_TAG, counted_buffer, &answer);
139
140 if (SBOX_ALL_OK != code) {
141 return false;
142 }
143 if (cookie != 717111 * 3) {
144 return false;
145 }
146 } else {
147 return false;
148 }
149 return true;
150 }
151
152 bool ProcessState::IsKernel32Loaded() {
153 return process_state_ != 0;
154 }
155
156 bool ProcessState::InitCalled() {
157 return process_state_ > 1;
158 }
159
160 bool ProcessState::RevertedToSelf() {
161 return process_state_ > 2;
162 }
163
164 void ProcessState::SetKernel32Loaded() {
165 if (!process_state_)
166 process_state_ = 1;
167 }
168
169 void ProcessState::SetInitCalled() {
170 if (process_state_ < 2)
171 process_state_ = 2;
172 }
173
174 void ProcessState::SetRevertedToSelf() {
175 if (process_state_ < 3)
176 process_state_ = 3;
177 }
178
179 ResultCode TargetServicesBase::DuplicateHandle(HANDLE source_handle,
180 DWORD target_process_id,
181 HANDLE* target_handle,
182 DWORD desired_access,
183 DWORD options) {
184 return sandbox::DuplicateHandleProxy(source_handle, target_process_id,
185 target_handle, desired_access, options);
186 }
187
188 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/src/target_services.h ('k') | sandbox/src/threadpool_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698