tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

32_set_delayed_integrity_on_process_acl.patch (3481B)


      1 # HG changeset patch
      2 # User Bob Owen <bobowencode@gmail.com>
      3 # Date 1709836178 0
      4 #      Thu Mar 07 18:29:38 2024 +0000
      5 # Node ID 2b9ab7e6c5a1630b497fe1543634cbaebdc395f8
      6 # Parent  f9c20c064d639a146ffa09ec832aee6dff44643d
      7 Bug 1889932 p1: Set process ACL to the delayed integrity level in LowerToken. r=yjuglaret!
      8 
      9 This allows us to maintain the same access to our process when the integrity
     10 level on our access token is dropped.
     11 This uses a lower level function for setting the label instead if the chromium
     12 wrappers, so that processes that haven't loaded ntmarta.dll don't need to.
     13 
     14 Differential Revision: https://phabricator.services.mozilla.com/D206784
     15 
     16 diff --git a/sandbox/win/src/target_services.cc b/sandbox/win/src/target_services.cc
     17 --- a/sandbox/win/src/target_services.cc
     18 +++ b/sandbox/win/src/target_services.cc
     19 @@ -126,16 +126,39 @@ bool SetProcessIntegrityLevel(IntegrityLevel integrity_level) {
     20       base::win::AccessToken::FromCurrentProcess(/*impersonation=*/false,
     21                                                  TOKEN_ADJUST_DEFAULT);
     22   if (!token) {
     23     return false;
     24   }
     25   return token->SetIntegrityLevel(*rid);
     26 }
     27 
     28 +void SetProcessAclIntegrityLevel(IntegrityLevel integrity_level) {
     29 +  absl::optional<DWORD> rid = GetIntegrityLevelRid(integrity_level);
     30 +  if (!rid) {
     31 +    // No mandatory level specified, we don't change it.
     32 +    return;
     33 +  }
     34 +
     35 +  // Set the integrity level for our process ACL, so we retain access to it.
     36 +  // We ignore failures in non-debug because this is not a security measure,
     37 +  // but some functionality may fail later in the process.
     38 +  base::win::SecurityDescriptor sdWrapper;
     39 +  if (!sdWrapper.SetMandatoryLabel(*rid, 0, 0)) {
     40 +    DCHECK(false);
     41 +    return;
     42 +  }
     43 +
     44 +  SECURITY_DESCRIPTOR sd;
     45 +  sdWrapper.ToAbsolute(sd);
     46 +  BOOL success = ::SetKernelObjectSecurity(::GetCurrentProcess(),
     47 +                                           LABEL_SECURITY_INFORMATION, &sd);
     48 +  DCHECK(success);
     49 +}
     50 +
     51 // Used as storage for g_target_services, because other allocation facilities
     52 // are not available early. We can't use a regular function static because on
     53 // VS2015, because the CRT tries to acquire a lock to guard initialization, but
     54 // this code runs before the CRT is initialized.
     55 char g_target_services_memory[sizeof(TargetServicesBase)];
     56 TargetServicesBase* g_target_services = nullptr;
     57 
     58 }  // namespace
     59 @@ -171,21 +194,23 @@ void TargetServicesBase::LowerToken() {
     60   if (ERROR_SUCCESS != ::RegDisablePredefinedCache())
     61     ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CACHEDISABLE);
     62   if (!WarmupWindowsLocales())
     63     ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_WARMUP);
     64   bool is_csrss_connected = true;
     65   if (!CloseOpenHandles(&is_csrss_connected))
     66     ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_CLOSEHANDLES);
     67   process_state_.SetCsrssConnected(is_csrss_connected);
     68 -  // Enabling mitigations must happen last otherwise handle closing breaks
     69 +  // Enabling mitigations must happen after the above measures otherwise handle
     70 +  // closing breaks.
     71   if (g_shared_delayed_mitigations &&
     72       !LockDownSecurityMitigations(g_shared_delayed_mitigations)) {
     73     ::TerminateProcess(::GetCurrentProcess(), SBOX_FATAL_MITIGATION);
     74   }
     75 +  SetProcessAclIntegrityLevel(g_shared_delayed_integrity_level);
     76 }
     77 
     78 ProcessState* TargetServicesBase::GetState() {
     79   return &process_state_;
     80 }
     81 
     82 TargetServicesBase* TargetServicesBase::GetInstance() {
     83   // Leak on purpose TargetServicesBase.