1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/win/src/handle_dispatcher.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,90 @@ 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_dispatcher.h" 1.9 + 1.10 +#include "base/win/scoped_handle.h" 1.11 +#include "sandbox/win/src/handle_interception.h" 1.12 +#include "sandbox/win/src/handle_policy.h" 1.13 +#include "sandbox/win/src/ipc_tags.h" 1.14 +#include "sandbox/win/src/policy_broker.h" 1.15 +#include "sandbox/win/src/policy_params.h" 1.16 +#include "sandbox/win/src/sandbox.h" 1.17 +#include "sandbox/win/src/sandbox_nt_util.h" 1.18 +#include "sandbox/win/src/sandbox_types.h" 1.19 +#include "sandbox/win/src/sandbox_utils.h" 1.20 + 1.21 +namespace sandbox { 1.22 + 1.23 +HandleDispatcher::HandleDispatcher(PolicyBase* policy_base) 1.24 + : policy_base_(policy_base) { 1.25 + static const IPCCall duplicate_handle_proxy = { 1.26 + {IPC_DUPLICATEHANDLEPROXY_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE, 1.27 + ULONG_TYPE}, 1.28 + reinterpret_cast<CallbackGeneric>(&HandleDispatcher::DuplicateHandleProxy) 1.29 + }; 1.30 + 1.31 + ipc_calls_.push_back(duplicate_handle_proxy); 1.32 +} 1.33 + 1.34 +bool HandleDispatcher::SetupService(InterceptionManager* manager, 1.35 + int service) { 1.36 + // We perform no interceptions for handles right now. 1.37 + switch (service) { 1.38 + case IPC_DUPLICATEHANDLEPROXY_TAG: 1.39 + return true; 1.40 + } 1.41 + 1.42 + return false; 1.43 +} 1.44 + 1.45 +bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc, 1.46 + HANDLE source_handle, 1.47 + DWORD target_process_id, 1.48 + DWORD desired_access, 1.49 + DWORD options) { 1.50 + NTSTATUS error; 1.51 + static NtQueryObject QueryObject = NULL; 1.52 + if (!QueryObject) 1.53 + ResolveNTFunctionPtr("NtQueryObject", &QueryObject); 1.54 + 1.55 + // Get a copy of the handle for use in the broker process. 1.56 + HANDLE handle_temp; 1.57 + if (!::DuplicateHandle(ipc->client_info->process, source_handle, 1.58 + ::GetCurrentProcess(), &handle_temp, 1.59 + 0, FALSE, DUPLICATE_SAME_ACCESS)) { 1.60 + ipc->return_info.win32_result = ::GetLastError(); 1.61 + return false; 1.62 + } 1.63 + base::win::ScopedHandle handle(handle_temp); 1.64 + 1.65 + // Get the object type (32 characters is safe; current max is 14). 1.66 + BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)]; 1.67 + OBJECT_TYPE_INFORMATION* type_info = 1.68 + reinterpret_cast<OBJECT_TYPE_INFORMATION*>(buffer); 1.69 + ULONG size = sizeof(buffer) - sizeof(wchar_t); 1.70 + error = QueryObject(handle, ObjectTypeInformation, type_info, size, &size); 1.71 + if (!NT_SUCCESS(error)) { 1.72 + ipc->return_info.win32_result = error; 1.73 + return false; 1.74 + } 1.75 + type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0'; 1.76 + 1.77 + CountedParameterSet<HandleTarget> params; 1.78 + params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer); 1.79 + params[HandleTarget::TARGET] = ParamPickerMake(target_process_id); 1.80 + 1.81 + EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG, 1.82 + params.GetBase()); 1.83 + ipc->return_info.win32_result = 1.84 + HandlePolicy::DuplicateHandleProxyAction(eval, *ipc->client_info, 1.85 + source_handle, 1.86 + target_process_id, 1.87 + &ipc->return_info.handle, 1.88 + desired_access, options); 1.89 + return true; 1.90 +} 1.91 + 1.92 +} // namespace sandbox 1.93 +