diff options
Diffstat (limited to 'security/sandbox/chromium-shim/patches/with_update/add_support_for_random_restricted_SID.patch')
-rw-r--r-- | security/sandbox/chromium-shim/patches/with_update/add_support_for_random_restricted_SID.patch | 461 |
1 files changed, 461 insertions, 0 deletions
diff --git a/security/sandbox/chromium-shim/patches/with_update/add_support_for_random_restricted_SID.patch b/security/sandbox/chromium-shim/patches/with_update/add_support_for_random_restricted_SID.patch new file mode 100644 index 0000000000..39f6b2538d --- /dev/null +++ b/security/sandbox/chromium-shim/patches/with_update/add_support_for_random_restricted_SID.patch @@ -0,0 +1,461 @@ +# HG changeset patch +# User Bob Owen <bobowencode@gmail.com> +# Date 1584045580 0 +# Thu Mar 12 20:39:40 2020 +0000 +# Node ID c996dbc3e3663fb372feb8e171562e86b09583b6 +# Parent f96efa1d9f5c676c0ee8fd80044a494258eff3d3 +Bug 1557282 Part 1: Take chromium commit c1ce57ea5d31208af589b4839390a44ab20b0c8f. r=handyman,gcp + +This adds AddRestrictingRandomSid feature, which fixes our issues with +SetLockdownDefaultDacl, apart from when we are running from a network drive. + +Differential Revision: https://phabricator.services.mozilla.com/D66610 + +diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token.cc b/security/sandbox/chromium/sandbox/win/src/restricted_token.cc +--- a/security/sandbox/chromium/sandbox/win/src/restricted_token.cc ++++ b/security/sandbox/chromium/sandbox/win/src/restricted_token.cc +@@ -141,16 +141,24 @@ DWORD RestrictedToken::GetRestrictedToke + } else { + // Modify the default dacl on the token to contain Restricted. + if (!AddSidToDefaultDacl(new_token.Get(), WinRestrictedCodeSid, + GRANT_ACCESS, GENERIC_ALL)) { + return ::GetLastError(); + } + } + ++ for (const auto& default_dacl_sid : sids_for_default_dacl_) { ++ if (!AddSidToDefaultDacl(new_token.Get(), std::get<0>(default_dacl_sid), ++ std::get<1>(default_dacl_sid), ++ std::get<2>(default_dacl_sid))) { ++ return ::GetLastError(); ++ } ++ } ++ + // Add user to default dacl. + if (!AddUserSidToDefaultDacl(new_token.Get(), GENERIC_ALL)) + return ::GetLastError(); + + DWORD error = SetTokenIntegrityLevel(new_token.Get(), integrity_level_); + if (ERROR_SUCCESS != error) + return error; + +@@ -405,9 +413,20 @@ DWORD RestrictedToken::SetIntegrityLevel + integrity_level_ = integrity_level; + return ERROR_SUCCESS; + } + + void RestrictedToken::SetLockdownDefaultDacl() { + lockdown_default_dacl_ = true; + } + ++DWORD RestrictedToken::AddDefaultDaclSid(const Sid& sid, ++ ACCESS_MODE access_mode, ++ ACCESS_MASK access) { ++ DCHECK(init_); ++ if (!init_) ++ return ERROR_NO_TOKEN; ++ ++ sids_for_default_dacl_.push_back(std::make_tuple(sid, access_mode, access)); ++ return ERROR_SUCCESS; ++} ++ + } // namespace sandbox +diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token.h b/security/sandbox/chromium/sandbox/win/src/restricted_token.h +--- a/security/sandbox/chromium/sandbox/win/src/restricted_token.h ++++ b/security/sandbox/chromium/sandbox/win/src/restricted_token.h +@@ -2,16 +2,17 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + + #ifndef SANDBOX_SRC_RESTRICTED_TOKEN_H_ + #define SANDBOX_SRC_RESTRICTED_TOKEN_H_ + + #include <windows.h> + ++#include <tuple> + #include <vector> + + #include <string> + + #include "base/macros.h" + #include "base/win/scoped_handle.h" + #include "sandbox/win/src/restricted_token_utils.h" + #include "sandbox/win/src/security_level.h" +@@ -169,23 +170,31 @@ class RestrictedToken { + // Sets the token integrity level. This is only valid on Vista. The integrity + // level cannot be higher than your current integrity level. + DWORD SetIntegrityLevel(IntegrityLevel integrity_level); + + // Set a flag which indicates the created token should have a locked down + // default DACL when created. + void SetLockdownDefaultDacl(); + ++ // Add a SID to the default DACL. These SIDs are added regardless of the ++ // SetLockdownDefaultDacl state. ++ DWORD AddDefaultDaclSid(const Sid& sid, ++ ACCESS_MODE access_mode, ++ ACCESS_MASK access); ++ + private: + // The list of restricting sids in the restricted token. + std::vector<Sid> sids_to_restrict_; + // The list of privileges to remove in the restricted token. + std::vector<LUID> privileges_to_disable_; + // The list of sids to mark as Deny Only in the restricted token. + std::vector<Sid> sids_for_deny_only_; ++ // The list of sids to add to the default DACL of the restricted token. ++ std::vector<std::tuple<Sid, ACCESS_MODE, ACCESS_MASK>> sids_for_default_dacl_; + // The token to restrict. Can only be set in a constructor. + base::win::ScopedHandle effective_token_; + // The token integrity level. Only valid on Vista. + IntegrityLevel integrity_level_; + // Tells if the object is initialized or not (if Init() has been called) + bool init_; + // Lockdown the default DACL when creating new tokens. + bool lockdown_default_dacl_; +diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc +--- a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc ++++ b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc +@@ -51,22 +51,29 @@ DWORD GetObjectSecurityDescriptor(HANDLE + + } // namespace + + DWORD CreateRestrictedToken(HANDLE effective_token, + TokenLevel security_level, + IntegrityLevel integrity_level, + TokenType token_type, + bool lockdown_default_dacl, ++ PSID unique_restricted_sid, + bool use_restricting_sids, + base::win::ScopedHandle* token) { + RestrictedToken restricted_token; + restricted_token.Init(effective_token); + if (lockdown_default_dacl) + restricted_token.SetLockdownDefaultDacl(); ++ if (unique_restricted_sid) { ++ restricted_token.AddDefaultDaclSid(Sid(unique_restricted_sid), GRANT_ACCESS, ++ GENERIC_ALL); ++ restricted_token.AddDefaultDaclSid(Sid(WinCreatorOwnerRightsSid), ++ GRANT_ACCESS, READ_CONTROL); ++ } + + std::vector<std::wstring> privilege_exceptions; + std::vector<Sid> sid_exceptions; + + bool deny_sids = true; + bool remove_privileges = true; + + switch (security_level) { +@@ -118,50 +125,60 @@ DWORD CreateRestrictedToken(HANDLE effec + sid_exceptions.push_back(WinAuthenticatedUserSid); + privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); + if (use_restricting_sids) { + restricted_token.AddRestrictingSid(WinBuiltinUsersSid); + restricted_token.AddRestrictingSid(WinWorldSid); + restricted_token.AddRestrictingSid(WinRestrictedCodeSid); + restricted_token.AddRestrictingSidCurrentUser(); + restricted_token.AddRestrictingSidLogonSession(); ++ if (unique_restricted_sid) ++ restricted_token.AddRestrictingSid(Sid(unique_restricted_sid)); + } + break; + } + case USER_LIMITED: { + sid_exceptions.push_back(WinBuiltinUsersSid); + sid_exceptions.push_back(WinWorldSid); + sid_exceptions.push_back(WinInteractiveSid); + privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); + if (use_restricting_sids) { + restricted_token.AddRestrictingSid(WinBuiltinUsersSid); + restricted_token.AddRestrictingSid(WinWorldSid); + restricted_token.AddRestrictingSid(WinRestrictedCodeSid); ++ if (unique_restricted_sid) ++ restricted_token.AddRestrictingSid(Sid(unique_restricted_sid)); + + // This token has to be able to create objects in BNO. + // Unfortunately, on Vista+, it needs the current logon sid + // in the token to achieve this. You should also set the process to be + // low integrity level so it can't access object created by other + // processes. + restricted_token.AddRestrictingSidLogonSession(); ++ } else { ++ restricted_token.AddUserSidForDenyOnly(); + } + break; + } + case USER_RESTRICTED: { + privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME); + restricted_token.AddUserSidForDenyOnly(); + if (use_restricting_sids) { + restricted_token.AddRestrictingSid(WinRestrictedCodeSid); ++ if (unique_restricted_sid) ++ restricted_token.AddRestrictingSid(Sid(unique_restricted_sid)); + } + break; + } + case USER_LOCKDOWN: { + restricted_token.AddUserSidForDenyOnly(); + if (use_restricting_sids) { + restricted_token.AddRestrictingSid(WinNullSid); ++ if (unique_restricted_sid) ++ restricted_token.AddRestrictingSid(Sid(unique_restricted_sid)); + } + break; + } + default: { return ERROR_BAD_ARGUMENTS; } + } + + DWORD err_code = ERROR_SUCCESS; + if (deny_sids) { +diff --git a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.h b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.h +--- a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.h ++++ b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.h +@@ -33,16 +33,17 @@ enum TokenType { IMPERSONATION = 0, PRIM + // 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. + DWORD CreateRestrictedToken(HANDLE effective_token, + TokenLevel security_level, + IntegrityLevel integrity_level, + TokenType token_type, + bool lockdown_default_dacl, ++ PSID unique_restricted_sid, + bool use_restricting_sids, + base::win::ScopedHandle* token); + + // Sets the integrity label on a object handle. + DWORD SetObjectIntegrityLabel(HANDLE handle, + SE_OBJECT_TYPE type, + const wchar_t* ace_access, + const wchar_t* integrity_level_sid); +diff --git a/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h b/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h +--- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h ++++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h +@@ -256,16 +256,20 @@ class TargetPolicy { + // ownership of the handle. + virtual void AddHandleToShare(HANDLE handle) = 0; + + // Locks down the default DACL of the created lockdown and initial tokens + // to restrict what other processes are allowed to access a process' kernel + // resources. + virtual void SetLockdownDefaultDacl() = 0; + ++ // Adds a restricting random SID to the restricted SIDs list as well as ++ // the default DACL. ++ virtual void AddRestrictingRandomSid() = 0; ++ + // Enable OPM API redirection when in Win32k lockdown. + virtual void SetEnableOPMRedirection() = 0; + // Enable OPM API emulation when in Win32k lockdown. + virtual bool GetEnableOPMRedirection() = 0; + + // Configure policy to use an AppContainer profile. |package_name| is the + // name of the profile to use. Specifying True for |create_profile| ensures + // the profile exists, if set to False process creation will fail if the +diff --git a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc +--- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc ++++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc +@@ -105,16 +105,17 @@ PolicyBase::PolicyBase() + delayed_integrity_level_(INTEGRITY_LEVEL_LAST), + mitigations_(0), + delayed_mitigations_(0), + is_csrss_connected_(true), + policy_maker_(nullptr), + policy_(nullptr), + lowbox_sid_(nullptr), + lockdown_default_dacl_(false), ++ add_restricting_random_sid_(false), + enable_opm_redirection_(false), + effective_token_(nullptr) { + ::InitializeCriticalSection(&lock_); + dispatcher_.reset(new TopLevelDispatcher(this)); + } + + PolicyBase::~PolicyBase() { + TargetSet::iterator it; +@@ -389,16 +390,20 @@ void PolicyBase::AddHandleToShare(HANDLE + + handles_to_share_.push_back(handle); + } + + void PolicyBase::SetLockdownDefaultDacl() { + lockdown_default_dacl_ = true; + } + ++void PolicyBase::AddRestrictingRandomSid() { ++ add_restricting_random_sid_ = true; ++} ++ + const base::HandlesToInheritVector& PolicyBase::GetHandlesBeingShared() { + return handles_to_share_; + } + + ResultCode PolicyBase::MakeJobObject(base::win::ScopedHandle* job) { + if (job_level_ == JOB_NONE) { + job->Close(); + return SBOX_ALL_OK; +@@ -413,22 +418,26 @@ ResultCode PolicyBase::MakeJobObject(bas + + *job = job_obj.Take(); + return SBOX_ALL_OK; + } + + ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial, + base::win::ScopedHandle* lockdown, + base::win::ScopedHandle* lowbox) { ++ Sid random_sid = Sid::GenerateRandomSid(); ++ PSID random_sid_ptr = nullptr; ++ if (add_restricting_random_sid_) ++ random_sid_ptr = random_sid.GetPSID(); ++ + // Create the 'naked' token. This will be the permanent token associated + // with the process and therefore with any thread that is not impersonating. +- DWORD result = +- CreateRestrictedToken(effective_token_, lockdown_level_, integrity_level_, +- PRIMARY, lockdown_default_dacl_, +- use_restricting_sids_, lockdown); ++ DWORD result = CreateRestrictedToken( ++ effective_token_, lockdown_level_, integrity_level_, PRIMARY, ++ lockdown_default_dacl_, random_sid_ptr, use_restricting_sids_, lockdown); + if (ERROR_SUCCESS != result) + return SBOX_ERROR_CANNOT_CREATE_RESTRICTED_TOKEN; + + // If we're launching on the alternate desktop we need to make sure the + // integrity label on the object is no higher than the sandboxed process's + // integrity level. So, we lower the label on the desktop process if it's + // not already low enough for our process. + if (use_alternate_desktop_ && integrity_level_ != INTEGRITY_LEVEL_LAST) { +@@ -485,20 +494,19 @@ ResultCode PolicyBase::MakeTokens(base:: + TOKEN_ALL_ACCESS)) { + return SBOX_ERROR_CANNOT_MODIFY_LOWBOX_TOKEN_DACL; + } + } + + // Create the 'better' token. We use this token as the one that the main + // thread uses when booting up the process. It should contain most of + // what we need (before reaching main( )) +- result = +- CreateRestrictedToken(effective_token_, initial_level_, integrity_level_, +- IMPERSONATION, lockdown_default_dacl_, +- use_restricting_sids_, initial); ++ result = CreateRestrictedToken( ++ effective_token_, initial_level_, integrity_level_, IMPERSONATION, ++ lockdown_default_dacl_, random_sid_ptr, use_restricting_sids_, initial); + if (ERROR_SUCCESS != result) + return SBOX_ERROR_CANNOT_CREATE_RESTRICTED_IMP_TOKEN; + + return SBOX_ALL_OK; + } + + PSID PolicyBase::GetLowBoxSid() const { + return lowbox_sid_; +diff --git a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.h b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.h +--- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.h ++++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.h +@@ -69,16 +69,17 @@ class PolicyBase final : public TargetPo + ResultCode AddRule(SubSystem subsystem, + Semantics semantics, + const wchar_t* pattern) override; + ResultCode AddDllToUnload(const wchar_t* dll_name) override; + ResultCode AddKernelObjectToClose(const wchar_t* handle_type, + const wchar_t* handle_name) override; + void AddHandleToShare(HANDLE handle) override; + void SetLockdownDefaultDacl() override; ++ void AddRestrictingRandomSid() override; + void SetEnableOPMRedirection() override; + bool GetEnableOPMRedirection() override; + ResultCode AddAppContainerProfile(const wchar_t* package_name, + bool create_profile) override; + scoped_refptr<AppContainerProfile> GetAppContainerProfile() override; + void SetEffectiveToken(HANDLE token) override; + + // Get the AppContainer profile as its internal type. +@@ -165,16 +166,17 @@ class PolicyBase final : public TargetPo + // This is a map of handle-types to names that we need to close in the + // target process. A null set means we need to close all handles of the + // given type. + HandleCloser handle_closer_; + PSID lowbox_sid_; + base::win::ScopedHandle lowbox_directory_; + std::unique_ptr<Dispatcher> dispatcher_; + bool lockdown_default_dacl_; ++ bool add_restricting_random_sid_; + + static HDESK alternate_desktop_handle_; + static HWINSTA alternate_winstation_handle_; + static HDESK alternate_desktop_local_winstation_handle_; + static IntegrityLevel alternate_desktop_integrity_level_label_; + static IntegrityLevel + alternate_desktop_local_winstation_integrity_level_label_; + +diff --git a/security/sandbox/chromium/sandbox/win/src/sid.cc b/security/sandbox/chromium/sandbox/win/src/sid.cc +--- a/security/sandbox/chromium/sandbox/win/src/sid.cc ++++ b/security/sandbox/chromium/sandbox/win/src/sid.cc +@@ -2,18 +2,20 @@ + // Use of this source code is governed by a BSD-style license that can be + // found in the LICENSE file. + + #include "sandbox/win/src/sid.h" + + #include <memory> + + #include <sddl.h> ++#include <stdlib.h> + + #include "base/logging.h" ++#include "base/rand_util.h" + #include "base/win/windows_version.h" + #include "sandbox/win/src/win_utils.h" + + namespace sandbox { + + namespace { + + DWORD WellKnownCapabilityToRid(WellKnownCapabilities capability) { +@@ -127,16 +129,24 @@ Sid Sid::FromSubAuthorities(PSID_IDENTIF + + Sid Sid::AllRestrictedApplicationPackages() { + SID_IDENTIFIER_AUTHORITY package_authority = {SECURITY_APP_PACKAGE_AUTHORITY}; + DWORD sub_authorities[] = {SECURITY_APP_PACKAGE_BASE_RID, + SECURITY_BUILTIN_PACKAGE_ANY_RESTRICTED_PACKAGE}; + return FromSubAuthorities(&package_authority, 2, sub_authorities); + } + ++Sid Sid::GenerateRandomSid() { ++ SID_IDENTIFIER_AUTHORITY package_authority = {SECURITY_NULL_SID_AUTHORITY}; ++ DWORD sub_authorities[4] = {}; ++ base::RandBytes(&sub_authorities, sizeof(sub_authorities)); ++ return FromSubAuthorities(&package_authority, _countof(sub_authorities), ++ sub_authorities); ++} ++ + PSID Sid::GetPSID() const { + return const_cast<BYTE*>(sid_); + } + + bool Sid::IsValid() const { + return !!::IsValidSid(GetPSID()); + } + +diff --git a/security/sandbox/chromium/sandbox/win/src/sid.h b/security/sandbox/chromium/sandbox/win/src/sid.h +--- a/security/sandbox/chromium/sandbox/win/src/sid.h ++++ b/security/sandbox/chromium/sandbox/win/src/sid.h +@@ -47,16 +47,18 @@ class Sid { + // Create a Sid from a SDDL format string, such as S-1-1-0. + static Sid FromSddlString(const wchar_t* sddl_sid); + // Create a Sid from a set of sub authorities. + static Sid FromSubAuthorities(PSID_IDENTIFIER_AUTHORITY identifier_authority, + BYTE sub_authority_count, + PDWORD sub_authorities); + // Create the restricted all application packages sid. + static Sid AllRestrictedApplicationPackages(); ++ // Generate a random SID value. ++ static Sid GenerateRandomSid(); + + // Returns sid_. + PSID GetPSID() const; + + // Gets whether the sid is valid. + bool IsValid() const; + + // Converts the SID to a SDDL format string. |