summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches/with_update/add_support_for_random_restricted_SID.patch
diff options
context:
space:
mode:
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.patch461
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.