Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "sandbox/win/src/handle_policy.h"
      6 
      7 #include <string>
      8 
      9 #include "base/win/scoped_handle.h"
     10 #include "sandbox/win/src/broker_services.h"
     11 #include "sandbox/win/src/ipc_tags.h"
     12 #include "sandbox/win/src/policy_engine_opcodes.h"
     13 #include "sandbox/win/src/policy_params.h"
     14 #include "sandbox/win/src/sandbox_types.h"
     15 #include "sandbox/win/src/sandbox_utils.h"
     16 
     17 namespace sandbox {
     18 
     19 bool HandlePolicy::GenerateRules(const wchar_t* type_name,
     20                                  TargetPolicy::Semantics semantics,
     21                                  LowLevelPolicy* policy) {
     22   PolicyRule duplicate_rule(ASK_BROKER);
     23 
     24   switch (semantics) {
     25     case TargetPolicy::HANDLES_DUP_ANY: {
     26       if (!duplicate_rule.AddNumberMatch(IF_NOT, HandleTarget::TARGET,
     27                                          ::GetCurrentProcessId(), EQUAL)) {
     28         return false;
     29       }
     30       break;
     31     }
     32 
     33     case TargetPolicy::HANDLES_DUP_BROKER: {
     34       if (!duplicate_rule.AddNumberMatch(IF, HandleTarget::TARGET,
     35                                          ::GetCurrentProcessId(), EQUAL)) {
     36         return false;
     37       }
     38       break;
     39     }
     40 
     41     default:
     42      return false;
     43   }
     44   if (!duplicate_rule.AddStringMatch(IF, HandleTarget::NAME, type_name,
     45                                      CASE_INSENSITIVE)) {
     46     return false;
     47   }
     48   if (!policy->AddRule(IPC_DUPLICATEHANDLEPROXY_TAG, &duplicate_rule)) {
     49     return false;
     50   }
     51   return true;
     52 }
     53 
     54 DWORD HandlePolicy::DuplicateHandleProxyAction(EvalResult eval_result,
     55                                                const ClientInfo& client_info,
     56                                                HANDLE source_handle,
     57                                                DWORD target_process_id,
     58                                                HANDLE* target_handle,
     59                                                DWORD desired_access,
     60                                                DWORD options) {
     61   // The only action supported is ASK_BROKER which means duplicate the handle.
     62   if (ASK_BROKER != eval_result) {
     63     return ERROR_ACCESS_DENIED;
     64   }
     65 
     66   base::win::ScopedHandle remote_target_process;
     67   if (target_process_id != ::GetCurrentProcessId()) {
     68     // Sandboxed children are dynamic, so we check that manually.
     69     if (!BrokerServicesBase::GetInstance()->IsActiveTarget(target_process_id)) {
     70       return ERROR_ACCESS_DENIED;
     71     }
     72 
     73     remote_target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE,
     74                                             target_process_id));
     75     if (!remote_target_process.IsValid())
     76       return ::GetLastError();
     77   }
     78 
     79   // If the policy didn't block us and we have no valid target, then the broker
     80   // (this process) is the valid target.
     81   HANDLE target_process = remote_target_process.IsValid() ?
     82                           remote_target_process : ::GetCurrentProcess();
     83   DWORD result = ERROR_SUCCESS;
     84   if (!::DuplicateHandle(client_info.process, source_handle, target_process,
     85                          target_handle, desired_access, FALSE,
     86                          options)) {
     87     return ::GetLastError();
     88   }
     89 
     90   return ERROR_SUCCESS;
     91 }
     92 
     93 }  // namespace sandbox
     94 
     95