| 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 <aclapi.h> | 5 #include <aclapi.h> |
| 6 #include <sddl.h> | 6 #include <sddl.h> |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "sandbox/win/src/restricted_token_utils.h" | 9 #include "sandbox/win/src/restricted_token_utils.h" |
| 10 | 10 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 case USER_LIMITED: { | 71 case USER_LIMITED: { |
| 72 sid_exceptions.push_back(WinBuiltinUsersSid); | 72 sid_exceptions.push_back(WinBuiltinUsersSid); |
| 73 sid_exceptions.push_back(WinWorldSid); | 73 sid_exceptions.push_back(WinWorldSid); |
| 74 sid_exceptions.push_back(WinInteractiveSid); | 74 sid_exceptions.push_back(WinInteractiveSid); |
| 75 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); | 75 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); |
| 76 restricted_token.AddRestrictingSid(WinBuiltinUsersSid); | 76 restricted_token.AddRestrictingSid(WinBuiltinUsersSid); |
| 77 restricted_token.AddRestrictingSid(WinWorldSid); | 77 restricted_token.AddRestrictingSid(WinWorldSid); |
| 78 restricted_token.AddRestrictingSid(WinRestrictedCodeSid); | 78 restricted_token.AddRestrictingSid(WinRestrictedCodeSid); |
| 79 | 79 |
| 80 // This token has to be able to create objects in BNO. | 80 // This token has to be able to create objects in BNO. |
| 81 // Unfortunately, on vista, it needs the current logon sid | 81 // Unfortunately, on Vista+, it needs the current logon sid |
| 82 // in the token to achieve this. You should also set the process to be | 82 // in the token to achieve this. You should also set the process to be |
| 83 // low integrity level so it can't access object created by other | 83 // low integrity level so it can't access object created by other |
| 84 // processes. | 84 // processes. |
| 85 if (base::win::GetVersion() >= base::win::VERSION_VISTA) | 85 restricted_token.AddRestrictingSidLogonSession(); |
| 86 restricted_token.AddRestrictingSidLogonSession(); | |
| 87 break; | 86 break; |
| 88 } | 87 } |
| 89 case USER_RESTRICTED: { | 88 case USER_RESTRICTED: { |
| 90 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); | 89 privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); |
| 91 restricted_token.AddUserSidForDenyOnly(); | 90 restricted_token.AddUserSidForDenyOnly(); |
| 92 restricted_token.AddRestrictingSid(WinRestrictedCodeSid); | 91 restricted_token.AddRestrictingSid(WinRestrictedCodeSid); |
| 93 break; | 92 break; |
| 94 } | 93 } |
| 95 case USER_LOCKDOWN: { | 94 case USER_LOCKDOWN: { |
| 96 restricted_token.AddUserSidForDenyOnly(); | 95 restricted_token.AddUserSidForDenyOnly(); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 191 case INTEGRITY_LEVEL_UNTRUSTED: | 190 case INTEGRITY_LEVEL_UNTRUSTED: |
| 192 return L"S-1-16-0"; | 191 return L"S-1-16-0"; |
| 193 case INTEGRITY_LEVEL_LAST: | 192 case INTEGRITY_LEVEL_LAST: |
| 194 return NULL; | 193 return NULL; |
| 195 } | 194 } |
| 196 | 195 |
| 197 NOTREACHED(); | 196 NOTREACHED(); |
| 198 return NULL; | 197 return NULL; |
| 199 } | 198 } |
| 200 DWORD SetTokenIntegrityLevel(HANDLE token, IntegrityLevel integrity_level) { | 199 DWORD SetTokenIntegrityLevel(HANDLE token, IntegrityLevel integrity_level) { |
| 201 if (base::win::GetVersion() < base::win::VERSION_VISTA) | |
| 202 return ERROR_SUCCESS; | |
| 203 | 200 |
| 204 const wchar_t* integrity_level_str = GetIntegrityLevelString(integrity_level); | 201 const wchar_t* integrity_level_str = GetIntegrityLevelString(integrity_level); |
| 205 if (!integrity_level_str) { | 202 if (!integrity_level_str) { |
| 206 // No mandatory level specified, we don't change it. | 203 // No mandatory level specified, we don't change it. |
| 207 return ERROR_SUCCESS; | 204 return ERROR_SUCCESS; |
| 208 } | 205 } |
| 209 | 206 |
| 210 PSID integrity_sid = NULL; | 207 PSID integrity_sid = NULL; |
| 211 if (!::ConvertStringSidToSid(integrity_level_str, &integrity_sid)) | 208 if (!::ConvertStringSidToSid(integrity_level_str, &integrity_sid)) |
| 212 return ::GetLastError(); | 209 return ::GetLastError(); |
| 213 | 210 |
| 214 TOKEN_MANDATORY_LABEL label = {}; | 211 TOKEN_MANDATORY_LABEL label = {}; |
| 215 label.Label.Attributes = SE_GROUP_INTEGRITY; | 212 label.Label.Attributes = SE_GROUP_INTEGRITY; |
| 216 label.Label.Sid = integrity_sid; | 213 label.Label.Sid = integrity_sid; |
| 217 | 214 |
| 218 DWORD size = sizeof(TOKEN_MANDATORY_LABEL) + ::GetLengthSid(integrity_sid); | 215 DWORD size = sizeof(TOKEN_MANDATORY_LABEL) + ::GetLengthSid(integrity_sid); |
| 219 BOOL result = ::SetTokenInformation(token, TokenIntegrityLevel, &label, | 216 BOOL result = ::SetTokenInformation(token, TokenIntegrityLevel, &label, |
| 220 size); | 217 size); |
| 221 auto last_error = ::GetLastError(); | 218 auto last_error = ::GetLastError(); |
| 222 ::LocalFree(integrity_sid); | 219 ::LocalFree(integrity_sid); |
| 223 | 220 |
| 224 return result ? ERROR_SUCCESS : last_error; | 221 return result ? ERROR_SUCCESS : last_error; |
| 225 } | 222 } |
| 226 | 223 |
| 227 DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level) { | 224 DWORD SetProcessIntegrityLevel(IntegrityLevel integrity_level) { |
| 228 if (base::win::GetVersion() < base::win::VERSION_VISTA) | |
| 229 return ERROR_SUCCESS; | |
| 230 | 225 |
| 231 // We don't check for an invalid level here because we'll just let it | 226 // We don't check for an invalid level here because we'll just let it |
| 232 // fail on the SetTokenIntegrityLevel call later on. | 227 // fail on the SetTokenIntegrityLevel call later on. |
| 233 if (integrity_level == INTEGRITY_LEVEL_LAST) { | 228 if (integrity_level == INTEGRITY_LEVEL_LAST) { |
| 234 // No mandatory level specified, we don't change it. | 229 // No mandatory level specified, we don't change it. |
| 235 return ERROR_SUCCESS; | 230 return ERROR_SUCCESS; |
| 236 } | 231 } |
| 237 | 232 |
| 238 HANDLE token_handle; | 233 HANDLE token_handle; |
| 239 if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT, | 234 if (!::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_DEFAULT, |
| 240 &token_handle)) | 235 &token_handle)) |
| 241 return ::GetLastError(); | 236 return ::GetLastError(); |
| 242 | 237 |
| 243 base::win::ScopedHandle token(token_handle); | 238 base::win::ScopedHandle token(token_handle); |
| 244 | 239 |
| 245 return SetTokenIntegrityLevel(token.Get(), integrity_level); | 240 return SetTokenIntegrityLevel(token.Get(), integrity_level); |
| 246 } | 241 } |
| 247 | 242 |
| 248 DWORD HardenTokenIntegrityLevelPolicy(HANDLE token) { | 243 DWORD HardenTokenIntegrityLevelPolicy(HANDLE token) { |
| 249 if (base::win::GetVersion() < base::win::VERSION_WIN7) | |
| 250 return ERROR_SUCCESS; | |
| 251 | 244 |
| 252 DWORD last_error = 0; | 245 DWORD last_error = 0; |
| 253 DWORD length_needed = 0; | 246 DWORD length_needed = 0; |
| 254 | 247 |
| 255 ::GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, | 248 ::GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, |
| 256 NULL, 0, &length_needed); | 249 NULL, 0, &length_needed); |
| 257 | 250 |
| 258 last_error = ::GetLastError(); | 251 last_error = ::GetLastError(); |
| 259 if (last_error != ERROR_INSUFFICIENT_BUFFER) | 252 if (last_error != ERROR_INSUFFICIENT_BUFFER) |
| 260 return last_error; | 253 return last_error; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 288 } | 281 } |
| 289 | 282 |
| 290 if (!::SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, | 283 if (!::SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, |
| 291 security_desc)) | 284 security_desc)) |
| 292 return ::GetLastError(); | 285 return ::GetLastError(); |
| 293 | 286 |
| 294 return ERROR_SUCCESS; | 287 return ERROR_SUCCESS; |
| 295 } | 288 } |
| 296 | 289 |
| 297 DWORD HardenProcessIntegrityLevelPolicy() { | 290 DWORD HardenProcessIntegrityLevelPolicy() { |
| 298 if (base::win::GetVersion() < base::win::VERSION_WIN7) | |
| 299 return ERROR_SUCCESS; | |
| 300 | 291 |
| 301 HANDLE token_handle; | 292 HANDLE token_handle; |
| 302 if (!::OpenProcessToken(GetCurrentProcess(), READ_CONTROL | WRITE_OWNER, | 293 if (!::OpenProcessToken(GetCurrentProcess(), READ_CONTROL | WRITE_OWNER, |
| 303 &token_handle)) | 294 &token_handle)) |
| 304 return ::GetLastError(); | 295 return ::GetLastError(); |
| 305 | 296 |
| 306 base::win::ScopedHandle token(token_handle); | 297 base::win::ScopedHandle token(token_handle); |
| 307 | 298 |
| 308 return HardenTokenIntegrityLevelPolicy(token.Get()); | 299 return HardenTokenIntegrityLevelPolicy(token.Get()); |
| 309 } | 300 } |
| 310 | 301 |
| 311 } // namespace sandbox | 302 } // namespace sandbox |
| OLD | NEW |