1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/handle_policy.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,94 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#include "sandbox/win/src/handle_policy.h" 1.9 + 1.10 +#include <string> 1.11 + 1.12 +#include "base/win/scoped_handle.h" 1.13 +#include "sandbox/win/src/broker_services.h" 1.14 +#include "sandbox/win/src/ipc_tags.h" 1.15 +#include "sandbox/win/src/policy_engine_opcodes.h" 1.16 +#include "sandbox/win/src/policy_params.h" 1.17 +#include "sandbox/win/src/sandbox_types.h" 1.18 +#include "sandbox/win/src/sandbox_utils.h" 1.19 + 1.20 +namespace sandbox { 1.21 + 1.22 +bool HandlePolicy::GenerateRules(const wchar_t* type_name, 1.23 + TargetPolicy::Semantics semantics, 1.24 + LowLevelPolicy* policy) { 1.25 + PolicyRule duplicate_rule(ASK_BROKER); 1.26 + 1.27 + switch (semantics) { 1.28 + case TargetPolicy::HANDLES_DUP_ANY: { 1.29 + if (!duplicate_rule.AddNumberMatch(IF_NOT, HandleTarget::TARGET, 1.30 + ::GetCurrentProcessId(), EQUAL)) { 1.31 + return false; 1.32 + } 1.33 + break; 1.34 + } 1.35 + 1.36 + case TargetPolicy::HANDLES_DUP_BROKER: { 1.37 + if (!duplicate_rule.AddNumberMatch(IF, HandleTarget::TARGET, 1.38 + ::GetCurrentProcessId(), EQUAL)) { 1.39 + return false; 1.40 + } 1.41 + break; 1.42 + } 1.43 + 1.44 + default: 1.45 + return false; 1.46 + } 1.47 + if (!duplicate_rule.AddStringMatch(IF, HandleTarget::NAME, type_name, 1.48 + CASE_INSENSITIVE)) { 1.49 + return false; 1.50 + } 1.51 + if (!policy->AddRule(IPC_DUPLICATEHANDLEPROXY_TAG, &duplicate_rule)) { 1.52 + return false; 1.53 + } 1.54 + return true; 1.55 +} 1.56 + 1.57 +DWORD HandlePolicy::DuplicateHandleProxyAction(EvalResult eval_result, 1.58 + const ClientInfo& client_info, 1.59 + HANDLE source_handle, 1.60 + DWORD target_process_id, 1.61 + HANDLE* target_handle, 1.62 + DWORD desired_access, 1.63 + DWORD options) { 1.64 + // The only action supported is ASK_BROKER which means duplicate the handle. 1.65 + if (ASK_BROKER != eval_result) { 1.66 + return ERROR_ACCESS_DENIED; 1.67 + } 1.68 + 1.69 + base::win::ScopedHandle remote_target_process; 1.70 + if (target_process_id != ::GetCurrentProcessId()) { 1.71 + // Sandboxed children are dynamic, so we check that manually. 1.72 + if (!BrokerServicesBase::GetInstance()->IsActiveTarget(target_process_id)) { 1.73 + return ERROR_ACCESS_DENIED; 1.74 + } 1.75 + 1.76 + remote_target_process.Set(::OpenProcess(PROCESS_DUP_HANDLE, FALSE, 1.77 + target_process_id)); 1.78 + if (!remote_target_process.IsValid()) 1.79 + return ::GetLastError(); 1.80 + } 1.81 + 1.82 + // If the policy didn't block us and we have no valid target, then the broker 1.83 + // (this process) is the valid target. 1.84 + HANDLE target_process = remote_target_process.IsValid() ? 1.85 + remote_target_process.Get() : ::GetCurrentProcess(); 1.86 + DWORD result = ERROR_SUCCESS; 1.87 + if (!::DuplicateHandle(client_info.process, source_handle, target_process, 1.88 + target_handle, desired_access, FALSE, 1.89 + options)) { 1.90 + return ::GetLastError(); 1.91 + } 1.92 + 1.93 + return ERROR_SUCCESS; 1.94 +} 1.95 + 1.96 +} // namespace sandbox 1.97 +