summaryrefslogtreecommitdiffstats
path: root/security/sandbox/chromium-shim/patches/with_update/add_support_for_random_restricted_SID.patch
blob: 39f6b2538d57d2d65e781c99b7ea99ba397829d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
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.