michael@0: // Copyright (c) 2012 The Chromium Authors. All rights reserved. michael@0: // Use of this source code is governed by a BSD-style license that can be michael@0: // found in the LICENSE file. michael@0: michael@0: #include "sandbox/win/src/handle_dispatcher.h" michael@0: michael@0: #include "base/win/scoped_handle.h" michael@0: #include "sandbox/win/src/handle_interception.h" michael@0: #include "sandbox/win/src/handle_policy.h" michael@0: #include "sandbox/win/src/ipc_tags.h" michael@0: #include "sandbox/win/src/policy_broker.h" michael@0: #include "sandbox/win/src/policy_params.h" michael@0: #include "sandbox/win/src/sandbox.h" michael@0: #include "sandbox/win/src/sandbox_nt_util.h" michael@0: #include "sandbox/win/src/sandbox_types.h" michael@0: #include "sandbox/win/src/sandbox_utils.h" michael@0: michael@0: namespace sandbox { michael@0: michael@0: HandleDispatcher::HandleDispatcher(PolicyBase* policy_base) michael@0: : policy_base_(policy_base) { michael@0: static const IPCCall duplicate_handle_proxy = { michael@0: {IPC_DUPLICATEHANDLEPROXY_TAG, VOIDPTR_TYPE, ULONG_TYPE, ULONG_TYPE, michael@0: ULONG_TYPE}, michael@0: reinterpret_cast(&HandleDispatcher::DuplicateHandleProxy) michael@0: }; michael@0: michael@0: ipc_calls_.push_back(duplicate_handle_proxy); michael@0: } michael@0: michael@0: bool HandleDispatcher::SetupService(InterceptionManager* manager, michael@0: int service) { michael@0: // We perform no interceptions for handles right now. michael@0: switch (service) { michael@0: case IPC_DUPLICATEHANDLEPROXY_TAG: michael@0: return true; michael@0: } michael@0: michael@0: return false; michael@0: } michael@0: michael@0: bool HandleDispatcher::DuplicateHandleProxy(IPCInfo* ipc, michael@0: HANDLE source_handle, michael@0: DWORD target_process_id, michael@0: DWORD desired_access, michael@0: DWORD options) { michael@0: NTSTATUS error; michael@0: static NtQueryObject QueryObject = NULL; michael@0: if (!QueryObject) michael@0: ResolveNTFunctionPtr("NtQueryObject", &QueryObject); michael@0: michael@0: // Get a copy of the handle for use in the broker process. michael@0: HANDLE handle_temp; michael@0: if (!::DuplicateHandle(ipc->client_info->process, source_handle, michael@0: ::GetCurrentProcess(), &handle_temp, michael@0: 0, FALSE, DUPLICATE_SAME_ACCESS)) { michael@0: ipc->return_info.win32_result = ::GetLastError(); michael@0: return false; michael@0: } michael@0: base::win::ScopedHandle handle(handle_temp); michael@0: michael@0: // Get the object type (32 characters is safe; current max is 14). michael@0: BYTE buffer[sizeof(OBJECT_TYPE_INFORMATION) + 32 * sizeof(wchar_t)]; michael@0: OBJECT_TYPE_INFORMATION* type_info = michael@0: reinterpret_cast(buffer); michael@0: ULONG size = sizeof(buffer) - sizeof(wchar_t); michael@0: error = QueryObject(handle, ObjectTypeInformation, type_info, size, &size); michael@0: if (!NT_SUCCESS(error)) { michael@0: ipc->return_info.win32_result = error; michael@0: return false; michael@0: } michael@0: type_info->Name.Buffer[type_info->Name.Length / sizeof(wchar_t)] = L'\0'; michael@0: michael@0: CountedParameterSet params; michael@0: params[HandleTarget::NAME] = ParamPickerMake(type_info->Name.Buffer); michael@0: params[HandleTarget::TARGET] = ParamPickerMake(target_process_id); michael@0: michael@0: EvalResult eval = policy_base_->EvalPolicy(IPC_DUPLICATEHANDLEPROXY_TAG, michael@0: params.GetBase()); michael@0: ipc->return_info.win32_result = michael@0: HandlePolicy::DuplicateHandleProxyAction(eval, *ipc->client_info, michael@0: source_handle, michael@0: target_process_id, michael@0: &ipc->return_info.handle, michael@0: desired_access, options); michael@0: return true; michael@0: } michael@0: michael@0: } // namespace sandbox michael@0: