Bug 1377555 - Part 2: Add option to Windows chromium sandbox policy to not use restricting SIDs. r=jimm, a=jcristau
authorBob Owen <bobowencode@gmail.com>
Tue, 11 Jul 2017 09:44:20 +0100
changeset 411980 4d917a319e6fe3e04fd98156bc776adfe64fb686
parent 411979 60fdd29667adb68cbe84c7a2dbe53dbfee63e7e6
child 411981 a15ebd1c523ce2a59ff771800a196a3a59838417
push id7514
push userryanvm@gmail.com
push dateMon, 17 Jul 2017 13:37:24 +0000
treeherdermozilla-beta@e26b1f5d635e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm, jcristau
bugs1377555
milestone55.0
Bug 1377555 - Part 2: Add option to Windows chromium sandbox policy to not use restricting SIDs. r=jimm, a=jcristau
security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc
security/sandbox/chromium/sandbox/win/src/restricted_token_utils.h
security/sandbox/chromium/sandbox/win/src/sandbox_policy.h
security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc
security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.h
--- a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc
+++ b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.cc
@@ -17,16 +17,17 @@
 #include "sandbox/win/src/sid.h"
 
 namespace sandbox {
 
 DWORD CreateRestrictedToken(TokenLevel security_level,
                             IntegrityLevel integrity_level,
                             TokenType token_type,
                             bool lockdown_default_dacl,
+                            bool use_restricting_sids,
                             base::win::ScopedHandle* token) {
   RestrictedToken restricted_token;
   restricted_token.Init(NULL);  // Initialized with the current process token
   if (lockdown_default_dacl)
     restricted_token.SetLockdownDefaultDacl();
 
   std::vector<base::string16> privilege_exceptions;
   std::vector<Sid> sid_exceptions;
@@ -40,19 +41,22 @@ DWORD CreateRestrictedToken(TokenLevel s
       deny_sids = false;
       remove_privileges = false;
       break;
     }
     case USER_RESTRICTED_SAME_ACCESS: {
       deny_sids = false;
       remove_privileges = false;
 
-      unsigned err_code = restricted_token.AddRestrictingSidAllSids();
-      if (ERROR_SUCCESS != err_code)
-        return err_code;
+      if (use_restricting_sids) {
+        unsigned err_code = restricted_token.AddRestrictingSidAllSids();
+        if (ERROR_SUCCESS != err_code) {
+          return err_code;
+        }
+      }
 
       break;
     }
     case USER_NON_ADMIN: {
       deny_sids = false;
       deny_only_sids.push_back(WinBuiltinAdministratorsSid);
       deny_only_sids.push_back(WinAccountAdministratorSid);
       deny_only_sids.push_back(WinAccountDomainAdminsSid);
@@ -66,49 +70,57 @@ DWORD CreateRestrictedToken(TokenLevel s
       break;
     }
     case USER_INTERACTIVE: {
       sid_exceptions.push_back(WinBuiltinUsersSid);
       sid_exceptions.push_back(WinWorldSid);
       sid_exceptions.push_back(WinInteractiveSid);
       sid_exceptions.push_back(WinAuthenticatedUserSid);
       privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
-      restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
-      restricted_token.AddRestrictingSid(WinWorldSid);
-      restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
-      restricted_token.AddRestrictingSidCurrentUser();
-      restricted_token.AddRestrictingSidLogonSession();
+      if (use_restricting_sids) {
+        restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
+        restricted_token.AddRestrictingSid(WinWorldSid);
+        restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
+        restricted_token.AddRestrictingSidCurrentUser();
+        restricted_token.AddRestrictingSidLogonSession();
+      }
       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);
-      restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
-      restricted_token.AddRestrictingSid(WinWorldSid);
-      restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
+      if (use_restricting_sids) {
+        restricted_token.AddRestrictingSid(WinBuiltinUsersSid);
+        restricted_token.AddRestrictingSid(WinWorldSid);
+        restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
 
-      // 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();
+        // 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();
+      }
       break;
     }
     case USER_RESTRICTED: {
       privilege_exceptions.push_back(SE_CHANGE_NOTIFY_NAME);
       restricted_token.AddUserSidForDenyOnly();
-      restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
+      if (use_restricting_sids) {
+        restricted_token.AddRestrictingSid(WinRestrictedCodeSid);
+      }
       break;
     }
     case USER_LOCKDOWN: {
       restricted_token.AddUserSidForDenyOnly();
-      restricted_token.AddRestrictingSid(WinNullSid);
+      if (use_restricting_sids) {
+        restricted_token.AddRestrictingSid(WinNullSid);
+      }
       break;
     }
     default: {
       return ERROR_BAD_ARGUMENTS;
     }
   }
 
   DWORD err_code = ERROR_SUCCESS;
--- a/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.h
+++ b/security/sandbox/chromium/sandbox/win/src/restricted_token_utils.h
@@ -35,16 +35,17 @@ enum TokenType {
 // running under the token.
 // 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(TokenLevel security_level,
                             IntegrityLevel integrity_level,
                             TokenType token_type,
                             bool lockdown_default_dacl,
+                            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);
 
 // Sets the integrity level on a token. This is only valid on Vista. It returns
--- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h
+++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy.h
@@ -95,16 +95,21 @@ class TargetPolicy {
   virtual ResultCode SetTokenLevel(TokenLevel initial, TokenLevel lockdown) = 0;
 
   // Returns the initial token level.
   virtual TokenLevel GetInitialTokenLevel() const = 0;
 
   // Returns the lockdown token level.
   virtual TokenLevel GetLockdownTokenLevel() const = 0;
 
+  // Sets that we should not use restricting SIDs in the access tokens. We need
+  // to do this in some circumstances even though it weakens the sandbox.
+  // The default is to use them.
+  virtual void SetDoNotUseRestrictingSIDs() = 0;
+
   // Sets the security level of the Job Object to which the target process will
   // belong. This setting is permanent and cannot be changed once the target
   // process is spawned. The job controls the global security settings which
   // can not be specified in the token security profile.
   // job_level: the security level for the job. See the explanation of each
   //   level in the JobLevel definition.
   // ui_exceptions: specify what specific rights that are disabled in the
   //   chosen job_level that need to be granted. Use this parameter to avoid
--- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc
+++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.cc
@@ -178,16 +178,20 @@ ResultCode PolicyBase::SetTokenLevel(Tok
 TokenLevel PolicyBase::GetInitialTokenLevel() const {
   return initial_level_;
 }
 
 TokenLevel PolicyBase::GetLockdownTokenLevel() const {
   return lockdown_level_;
 }
 
+void PolicyBase::SetDoNotUseRestrictingSIDs() {
+  use_restricting_sids_ = false;
+}
+
 ResultCode PolicyBase::SetJobLevel(JobLevel job_level, uint32_t ui_exceptions) {
   if (memory_limit_ && job_level == JOB_NONE) {
     return SBOX_ERROR_BAD_PARAMS;
   }
   job_level_ = job_level;
   ui_exceptions_ = ui_exceptions;
   return SBOX_ALL_OK;
 }
@@ -432,17 +436,18 @@ ResultCode PolicyBase::MakeJobObject(bas
 
 ResultCode PolicyBase::MakeTokens(base::win::ScopedHandle* initial,
                                   base::win::ScopedHandle* lockdown,
                                   base::win::ScopedHandle* lowbox) {
   // 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(lockdown_level_, integrity_level_, PRIMARY,
-                            lockdown_default_dacl_, lockdown);
+                            lockdown_default_dacl_, use_restricting_sids_,
+                            lockdown);
   if (ERROR_SUCCESS != result)
     return SBOX_ERROR_GENERIC;
 
   // 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 (alternate_desktop_handle_ && use_alternate_desktop_ &&
@@ -488,17 +493,18 @@ ResultCode PolicyBase::MakeTokens(base::
     lowbox->Set(token_lowbox);
   }
 
   // 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(initial_level_, integrity_level_, IMPERSONATION,
-                            lockdown_default_dacl_, initial);
+                            lockdown_default_dacl_, use_restricting_sids_,
+                            initial);
   if (ERROR_SUCCESS != result)
     return SBOX_ERROR_GENERIC;
 
   return SBOX_ALL_OK;
 }
 
 PSID PolicyBase::GetLowBoxSid() const {
   return lowbox_sid_;
--- a/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.h
+++ b/security/sandbox/chromium/sandbox/win/src/sandbox_policy_base.h
@@ -37,16 +37,17 @@ class PolicyBase final : public TargetPo
   PolicyBase();
 
   // TargetPolicy:
   void AddRef() override;
   void Release() override;
   ResultCode SetTokenLevel(TokenLevel initial, TokenLevel lockdown) override;
   TokenLevel GetInitialTokenLevel() const override;
   TokenLevel GetLockdownTokenLevel() const override;
+  void SetDoNotUseRestrictingSIDs() final;
   ResultCode SetJobLevel(JobLevel job_level, uint32_t ui_exceptions) override;
   JobLevel GetJobLevel() const override;
   ResultCode SetJobMemoryLimit(size_t memory_limit) override;
   ResultCode SetAlternateDesktop(bool alternate_winstation) override;
   base::string16 GetAlternateDesktop() const override;
   ResultCode CreateAlternateDesktop(bool alternate_winstation) override;
   void DestroyAlternateDesktop() override;
   ResultCode SetIntegrityLevel(IntegrityLevel integrity_level) override;
@@ -122,16 +123,17 @@ class PolicyBase final : public TargetPo
   // The policy takes ownership of them.
   typedef std::list<TargetProcess*> TargetSet;
   TargetSet targets_;
   // Standard object-lifetime reference counter.
   volatile LONG ref_count;
   // The user-defined global policy settings.
   TokenLevel lockdown_level_;
   TokenLevel initial_level_;
+  bool use_restricting_sids_ = true;
   JobLevel job_level_;
   uint32_t ui_exceptions_;
   size_t memory_limit_;
   bool use_alternate_desktop_;
   bool use_alternate_winstation_;
   // Helps the file system policy initialization.
   bool file_system_init_;
   bool relaxed_interceptions_;