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

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

Issue 1851213002: Remove sandbox on Windows. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix nacl compile issues Created 4 years, 8 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
« no previous file with comments | « sandbox/win/src/restricted_token_utils.h ('k') | sandbox/win/src/sandbox.h » ('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 <aclapi.h>
6 #include <sddl.h>
7 #include <vector>
8
9 #include "sandbox/win/src/restricted_token_utils.h"
10
11 #include "base/logging.h"
12 #include "base/win/scoped_handle.h"
13 #include "base/win/windows_version.h"
14 #include "sandbox/win/src/job.h"
15 #include "sandbox/win/src/restricted_token.h"
16 #include "sandbox/win/src/security_level.h"
17 #include "sandbox/win/src/sid.h"
18
19 namespace sandbox {
20
21 DWORD CreateRestrictedToken(TokenLevel security_level,
22 IntegrityLevel integrity_level,
23 TokenType token_type,
24 bool lockdown_default_dacl,
25 base::win::ScopedHandle* token) {
26 RestrictedToken restricted_token;
27 restricted_token.Init(NULL); // Initialized with the current process token
28 if (lockdown_default_dacl)
29 restricted_token.SetLockdownDefaultDacl();
30
31 std::vector<base::string16> privilege_exceptions;
32 std::vector<Sid> sid_exceptions;
33
34 bool deny_sids = true;
35 bool remove_privileges = true;
36
37 switch (security_level) {
38 case USER_UNPROTECTED: {
39 deny_sids = false;
40 remove_privileges = false;
41 break;
42 }
43 case USER_RESTRICTED_SAME_ACCESS: {
44 deny_sids = false;
45 remove_privileges = false;
46
47 unsigned err_code = restricted_token.AddRestrictingSidAllSids();
48 if (ERROR_SUCCESS != err_code)
49 return err_code;
50
51 break;
52 }
53 case USER_NON_ADMIN: {
54 sid_exceptions.push_back(WinBuiltinUsersSid);
55 sid_exceptions.push_back(WinWorldSid);
56 sid_exceptions.push_back(WinInteractiveSid);
57 sid_exceptions.push_back(WinAuthenticatedUserSid);
58 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
59 break;
60 }
61 case USER_INTERACTIVE: {
62 sid_exceptions.push_back(WinBuiltinUsersSid);
63 sid_exceptions.push_back(WinWorldSid);
64 sid_exceptions.push_back(WinInteractiveSid);
65 sid_exceptions.push_back(WinAuthenticatedUserSid);
66 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
67 restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
68 restricted_token.AddRestrictingSid(WinWorldSid);
69 restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
70 restricted_token.AddRestrictingSidCurrentUser();
71 restricted_token.AddRestrictingSidLogonSession();
72 break;
73 }
74 case USER_LIMITED: {
75 sid_exceptions.push_back(WinBuiltinUsersSid);
76 sid_exceptions.push_back(WinWorldSid);
77 sid_exceptions.push_back(WinInteractiveSid);
78 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
79 restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
80 restricted_token.AddRestrictingSid(WinWorldSid);
81 restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
82
83 // This token has to be able to create objects in BNO.
84 // Unfortunately, on Vista+, it needs the current logon sid
85 // in the token to achieve this. You should also set the process to be
86 // low integrity level so it can't access object created by other
87 // processes.
88 restricted_token.AddRestrictingSidLogonSession();
89 break;
90 }
91 case USER_RESTRICTED: {
92 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
93 restricted_token.AddUserSidForDenyOnly();
94 restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
95 break;
96 }
97 case USER_LOCKDOWN: {
98 restricted_token.AddUserSidForDenyOnly();
99 restricted_token.AddRestrictingSid(WinNullSid);
100 break;
101 }
102 default: {
103 return ERROR_BAD_ARGUMENTS;
104 }
105 }
106
107 DWORD err_code = ERROR_SUCCESS;
108 if (deny_sids) {
109 err_code = restricted_token.AddAllSidsForDenyOnly(&sid_exceptions);
110 if (ERROR_SUCCESS != err_code)
111 return err_code;
112 }
113
114 if (remove_privileges) {
115 err_code = restricted_token.DeleteAllPrivileges(&privilege_exceptions);
116 if (ERROR_SUCCESS != err_code)
117 return err_code;
118 }
119
120 restricted_token.SetIntegrityLevel(integrity_level);
121
122 switch (token_type) {
123 case PRIMARY: {
124 err_code = restricted_token.GetRestrictedToken(token);
125 break;
126 }
127 case IMPERSONATION: {
128 err_code = restricted_token.GetRestrictedTokenForImpersonation(token);
129 break;
130 }
131 default: {
132 err_code = ERROR_BAD_ARGUMENTS;
133 break;
134 }
135 }
136
137 return err_code;
138 }
139
140 DWORD SetObjectIntegrityLabel(HANDLE handle, SE_OBJECT_TYPE type,
141 const wchar_t* ace_access,
142 const wchar_t* integrity_level_sid) {
143 // Build the SDDL string for the label.
144 base::string16 sddl = L"S:("; // SDDL for a SACL.
145 sddl += SDDL_MANDATORY_LABEL; // Ace Type is "Mandatory Label".
146 sddl += L";;"; // No Ace Flags.
147 sddl += ace_access; // Add the ACE access.
148 sddl += L";;;"; // No ObjectType and Inherited Object Type.
149 sddl += integrity_level_sid; // Trustee Sid.
150 sddl += L")";
151
152 DWORD error = ERROR_SUCCESS;
153 PSECURITY_DESCRIPTOR sec_desc = NULL;
154
155 PACL sacl = NULL;
156 BOOL sacl_present = FALSE;
157 BOOL sacl_defaulted = FALSE;
158
159 if (::ConvertStringSecurityDescriptorToSecurityDescriptorW(sddl.c_str(),
160 SDDL_REVISION,
161 &sec_desc, NULL)) {
162 if (::GetSecurityDescriptorSacl(sec_desc, &sacl_present, &sacl,
163 &sacl_defaulted)) {
164 error = ::SetSecurityInfo(handle, type,
165 LABEL_SECURITY_INFORMATION, NULL, NULL, NULL,
166 sacl);
167 } else {
168 error = ::GetLastError();
169 }
170
171 ::LocalFree(sec_desc);
172 } else {
173 return::GetLastError();
174 }
175
176 return error;
177 }
178
179 const wchar_t* GetIntegrityLevelString(IntegrityLevel integrity_level) {
180 switch (integrity_level) {
181 case INTEGRITY_LEVEL_SYSTEM:
182 return L"S-1-16-16384";
183 case INTEGRITY_LEVEL_HIGH:
184 return L"S-1-16-12288";
185 case INTEGRITY_LEVEL_MEDIUM:
186 return L"S-1-16-8192";
187 case INTEGRITY_LEVEL_MEDIUM_LOW:
188 return L"S-1-16-6144";
189 case INTEGRITY_LEVEL_LOW:
190 return L"S-1-16-4096";
191 case INTEGRITY_LEVEL_BELOW_LOW:
192 return L"S-1-16-2048";
193 case INTEGRITY_LEVEL_UNTRUSTED:
194 return L"S-1-16-0";
195 case INTEGRITY_LEVEL_LAST:
196 return NULL;
197 }
198
199 NOTREACHED();
200 return NULL;
201 }
202 DWORD SetTokenIntegrityLevel(HANDLE token, IntegrityLevel integrity_level) {
203
204 const wchar_t* integrity_level_str = GetIntegrityLevelString(integrity_level);
205 if (!integrity_level_str) {
206 // No mandatory level specified, we don't change it.
207 return ERROR_SUCCESS;
208 }
209
210 PSID integrity_sid = NULL;
211 if (!::ConvertStringSidToSid(integrity_level_str, &integrity_sid))
212 return ::GetLastError();
213
214 TOKEN_MANDATORY_LABEL label = {};
215 label.Label.Attributes = SE_GROUP_INTEGRITY;
216 label.Label.Sid = integrity_sid;
217
218 DWORD size = sizeof(TOKEN_MANDATORY_LABEL) + ::GetLengthSid(integrity_sid);
219 BOOL result = ::SetTokenInformation(token, TokenIntegrityLevel, &label,
220 size);
221 auto last_error = ::GetLastError();
222 ::LocalFree(integrity_sid);
223
224 return result ? ERROR_SUCCESS : last_error;
225 }
226
227 DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level) {
228
229 // We don't check for an invalid level here because we'll just let it
230 // fail on the SetTokenIntegrityLevel call later on.
231 if (integrity_level == INTEGRITY_LEVEL_LAST) {
232 // No mandatory level specified, we don't change it.
233 return ERROR_SUCCESS;
234 }
235
236 HANDLE token_handle;
237 if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT,
238 &token_handle))
239 return ::GetLastError();
240
241 base::win::ScopedHandle token(token_handle);
242
243 return SetTokenIntegrityLevel(token.Get(), integrity_level);
244 }
245
246 DWORD HardenTokenIntegrityLevelPolicy(HANDLE token) {
247
248 DWORD last_error = 0;
249 DWORD length_needed = 0;
250
251 ::GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION,
252 NULL, 0, &length_needed);
253
254 last_error = ::GetLastError();
255 if (last_error != ERROR_INSUFFICIENT_BUFFER)
256 return last_error;
257
258 std::vector<char> security_desc_buffer(length_needed);
259 PSECURITY_DESCRIPTOR security_desc =
260 reinterpret_cast<PSECURITY_DESCRIPTOR>(&security_desc_buffer[0]);
261
262 if (!::GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION,
263 security_desc, length_needed,
264 &length_needed))
265 return ::GetLastError();
266
267 PACL sacl = NULL;
268 BOOL sacl_present = FALSE;
269 BOOL sacl_defaulted = FALSE;
270
271 if (!::GetSecurityDescriptorSacl(security_desc, &sacl_present,
272 &sacl, &sacl_defaulted))
273 return ::GetLastError();
274
275 for (DWORD ace_index = 0; ace_index < sacl->AceCount; ++ace_index) {
276 PSYSTEM_MANDATORY_LABEL_ACE ace;
277
278 if (::GetAce(sacl, ace_index, reinterpret_cast<LPVOID*>(&ace))
279 && ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) {
280 ace->Mask |= SYSTEM_MANDATORY_LABEL_NO_READ_UP
281 | SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP;
282 break;
283 }
284 }
285
286 if (!::SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION,
287 security_desc))
288 return ::GetLastError();
289
290 return ERROR_SUCCESS;
291 }
292
293 DWORD HardenProcessIntegrityLevelPolicy() {
294
295 HANDLE token_handle;
296 if (!::OpenProcessToken(GetCurrentProcess(), READ_CONTROL | WRITE_OWNER,
297 &token_handle))
298 return ::GetLastError();
299
300 base::win::ScopedHandle token(token_handle);
301
302 return HardenTokenIntegrityLevelPolicy(token.Get());
303 }
304
305 } // namespace sandbox
OLDNEW
« no previous file with comments | « sandbox/win/src/restricted_token_utils.h ('k') | sandbox/win/src/sandbox.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698