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 NTSTATUS error; 48 static NtQueryObject QueryObject = NULL; 49 if (!QueryObject) 50 ResolveNTFunctionPtr("NtQueryObject", &QueryObject); 51 52 // Get a copy of the handle for use in the broker process. 53 HANDLE handle_temp; 54 if (!::DuplicateHandle(ipc->client_info->process, source_handle, 55 ::GetCurrentProcess(), &handle_temp, 56 0, FALSE, DUPLICATE_SAME_ACCESS)) { 57 ipc->return_info.win32_result = ::GetLastError(); 58 return false; 59 } 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 error = QueryObject(handle, ObjectTypeInformation, type_info, size, &size); 68 if (!NT_SUCCESS(error)) { 69 ipc->return_info.win32_result = error; 70 return false; 71 } 72 type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0'; 73 74 CountedParameterSet<HandleTarget> params; 75 params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer); 76 params[HandleTarget::TARGET] = ParamPickerMake(target_process_id); 77 78 EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG, 79 params.GetBase()); 80 ipc->return_info.win32_result = 81 HandlePolicy::DuplicateHandleProxyAction(eval, *ipc->client_info, 82 source_handle, 83 target_process_id, 84 &ipc->return_info.handle, 85 desired_access, options); 86 return true; 87} 88 89} // namespace sandbox 90 91