diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token.cc b/security/sandbox/chromium/sandbox/win/src/restricted_token.cc index b696a24b5081..331faa013b93 100644 --- a/security/sandbox/chromium/sandbox/win/src/restricted_token.cc +++ b/security/sandbox/chromium/sandbox/win/src/restricted_token.cc @@ -259,6 +259,40 @@ DWORD RestrictedToken::AddAllSidsForDenyOnly(std::vector<Sid> *exceptions) { return ERROR_SUCCESS; } +DWORD RestrictedToken::AddDenyOnlySids(const std::vector<Sid>& deny_only_sids) { + DCHECK(init_); + if (!init_) { + return ERROR_NO_TOKEN; + } + + DWORD error; + std::unique_ptr<BYTE[]> buffer = + GetTokenInfo(effective_token_, TokenGroups, &error); + + if (!buffer) { + return error; + } + + TOKEN_GROUPS* token_groups = reinterpret_cast<TOKEN_GROUPS*>(buffer.get()); + + // Build the list of the deny only group SIDs + for (unsigned int i = 0; i < token_groups->GroupCount ; ++i) { + if ((token_groups->Groups[i].Attributes & SE_GROUP_INTEGRITY) == 0 && + (token_groups->Groups[i].Attributes & SE_GROUP_LOGON_ID) == 0) { + for (unsigned int j = 0; j < deny_only_sids.size(); ++j) { + if (::EqualSid(const_cast<SID*>(deny_only_sids[j].GetPSID()), + token_groups->Groups[i].Sid)) { + sids_for_deny_only_.push_back( + reinterpret_cast<SID*>(token_groups->Groups[i].Sid)); + break; + } + } + } + } + + return ERROR_SUCCESS; +} + DWORD RestrictedToken::AddSidForDenyOnly(const Sid &sid) { DCHECK(init_); if (!init_) diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token.h b/security/sandbox/chromium/sandbox/win/src/restricted_token.h index 584cd3ad6dbb..feb2d2978651 100644 --- a/security/sandbox/chromium/sandbox/win/src/restricted_token.h +++ b/security/sandbox/chromium/sandbox/win/src/restricted_token.h @@ -88,6 +88,17 @@ class RestrictedToken { // access to any resource. It can only be used to deny access. DWORD AddAllSidsForDenyOnly(std::vector<Sid> *exceptions); + // Lists all sids in the token and mark them as Deny Only if present in the + // deny_only_sids parameter. + // + // If the function succeeds, the return value is ERROR_SUCCESS. If the + // function fails, the return value is the win32 error code corresponding to + // the error. + // + // Note: A Sid marked for Deny Only in a token cannot be used to grant + // access to any resource. It can only be used to deny access. + DWORD AddDenyOnlySids(const std::vector<Sid>& deny_only_sids); + // Adds a user or group SID for Deny Only in the restricted token. // Parameter: sid is the SID to add in the Deny Only list. // The return value is always ERROR_SUCCESS. diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc index 9f1ebd810cc7..31e36cf69e47 100644 --- a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc +++ b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc @@ -30,6 +30,7 @@ DWORD CreateRestrictedToken(TokenLevel security_level, std::vector<base::string16> privilege_exceptions; std::vector<Sid> sid_exceptions; + std::vector<Sid> deny_only_sids; bool deny_sids = true; bool remove_privileges = true; @@ -51,10 +52,16 @@ DWORD CreateRestrictedToken(TokenLevel security_level, break; } case USER_NON_ADMIN: { - sid_exceptions.push_back(WinBuiltinUsersSid); - sid_exceptions.push_back(WinWorldSid); - sid_exceptions.push_back(WinInteractiveSid); - sid_exceptions.push_back(WinAuthenticatedUserSid); + deny_sids = false; + deny_only_sids.push_back(WinBuiltinAdministratorsSid); + deny_only_sids.push_back(WinAccountAdministratorSid); + deny_only_sids.push_back(WinAccountDomainAdminsSid); + deny_only_sids.push_back(WinAccountCertAdminsSid); + deny_only_sids.push_back(WinAccountSchemaAdminsSid); + deny_only_sids.push_back(WinAccountEnterpriseAdminsSid); + deny_only_sids.push_back(WinAccountPolicyAdminsSid); + deny_only_sids.push_back(WinBuiltinHyperVAdminsSid); + deny_only_sids.push_back(WinLocalAccountAndAdministratorSid); privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); break; } @@ -109,6 +116,11 @@ DWORD CreateRestrictedToken(TokenLevel security_level, err_code = restricted_token.AddAllSidsForDenyOnly(&sid_exceptions); if (ERROR_SUCCESS != err_code) return err_code; + } else if (!deny_only_sids.empty()) { + err_code = restricted_token.AddDenyOnlySids(deny_only_sids); + if (ERROR_SUCCESS != err_code) { + return err_code; + } } if (remove_privileges) {