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_dispatcher.h" 6 7#include "base/win/scoped_handle.h" 8#include "sandbox/win/src/handle_interception.h" 9#include "sandbox/win/src/handle_policy.h" 10#include "sandbox/win/src/ipc_tags.h" 11#include "sandbox/win/src/policy_broker.h" 12#include "sandbox/win/src/policy_params.h" 13#include "sandbox/win/src/sandbox.h" 14#include "sandbox/win/src/sandbox_nt_util.h" 15#include "sandbox/win/src/sandbox_types.h" 16#include "sandbox/win/src/sandbox_utils.h" 17 18namespace sandbox { 19 20HandleDispatcher::HandleDispatcher(PolicyBase* policy_base) 21 : policy_base_(policy_base) { 22 static const IPCCall duplicate_handle_proxy = { 23 {IPC_DUPLICATEHANDLEPROXY_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE, 24 ULONG_TYPE}, 25 reinterpret_cast<CallbackGeneric>(&HandleDispatcher::DuplicateHandleProxy) 26 }; 27 28 ipc_calls_.push_back(duplicate_handle_proxy); 29} 30 31bool HandleDispatcher::SetupService(InterceptionManager* manager, 32 int service) { 33 // We perform no interceptions for handles right now. 34 switch (service) { 35 case IPC_DUPLICATEHANDLEPROXY_TAG: 36 return true; 37 } 38 39 return false; 40} 41 42bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc, 43 HANDLE source_handle, 44 DWORD target_process_id, 45 DWORD desired_access, 46 DWORD options) { 47 static NtQueryObject QueryObject = NULL; 48 if (!QueryObject) 49 ResolveNTFunctionPtr("NtQueryObject", &QueryObject); 50 51 // Get a copy of the handle for use in the broker process. 52 HANDLE handle_temp; 53 if (!::DuplicateHandle(ipc->client_info->process, source_handle, 54 ::GetCurrentProcess(), &handle_temp, 55 0, FALSE, DUPLICATE_SAME_ACCESS | options)) { 56 ipc->return_info.win32_result = ::GetLastError(); 57 return false; 58 } 59 options &= ~DUPLICATE_CLOSE_SOURCE; 60 base::win::ScopedHandle handle(handle_temp); 61 62 // Get the object type (32 characters is safe; current max is 14). 63 BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)]; 64 OBJECT_TYPE_INFORMATION* type_info = 65 reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer); 66 ULONG size = sizeof(buffer) - sizeof(wchar_t); 67 NTSTATUS error = 68 QueryObject(handle.Get(), ObjectTypeInformation, type_info, size, &size); 69 if (!NT_SUCCESS(error)) { 70 ipc->return_info.nt_status = error; 71 return false; 72 } 73 type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0'; 74 75 CountedParameterSet<HandleTarget> params; 76 params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer); 77 params[HandleTarget::TARGET] = ParamPickerMake(target_process_id); 78 79 EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG, 80 params.GetBase()); 81 ipc->return_info.win32_result = 82 HandlePolicy::DuplicateHandleProxyAction(eval, handle.Get(), 83 target_process_id, 84 &ipc->return_info.handle, 85 desired_access, options); 86 return true; 87} 88 89} // namespace sandbox 90 91