| Index: sandbox/win/src/lpc_dispatcher.cc
|
| diff --git a/sandbox/win/src/lpc_dispatcher.cc b/sandbox/win/src/lpc_dispatcher.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..28410fe65f470afdd283628dd2e797d85b539a31
|
| --- /dev/null
|
| +++ b/sandbox/win/src/lpc_dispatcher.cc
|
| @@ -0,0 +1,96 @@
|
| +// Copyright (c) 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "sandbox/win/src/lpc_dispatcher.h"
|
| +
|
| +#include "base/win/windows_version.h"
|
| +#include "sandbox/win/src/crosscall_client.h"
|
| +#include "sandbox/win/src/interception.h"
|
| +#include "sandbox/win/src/interceptors.h"
|
| +#include "sandbox/win/src/ipc_tags.h"
|
| +#include "sandbox/win/src/policy_broker.h"
|
| +#include "sandbox/win/src/policy_params.h"
|
| +#include "sandbox/win/src/sandbox.h"
|
| +#include "sandbox/win/src/lpc_interception.h"
|
| +// #include "sandbox/win/src/sync_policy.h"
|
| +
|
| +namespace sandbox {
|
| +
|
| +LpcDispatcher::LpcDispatcher(PolicyBase* policy_base)
|
| + : policy_base_(policy_base) {
|
| + static const IPCCall connect_params = {
|
| + {IPC_NTCONNECTALPCPORT_TAG, {WCHAR_TYPE}},
|
| + reinterpret_cast<CallbackGeneric>(&LpcDispatcher::AlpcConnectPort)};
|
| +
|
| + ipc_calls_.push_back(connect_params);
|
| +}
|
| +
|
| +bool LpcDispatcher::SetupService(InterceptionManager* manager,
|
| + int service) {
|
| + if (service == IPC_NTCONNECTALPCPORT_TAG)
|
| + return INTERCEPT_NT(manager, NtAlpcConnectPort, NTCONNECTALPCPORT_ID, 48);
|
| + return true;
|
| +}
|
| +
|
| +bool LpcDispatcher::AlpcConnectPort(IPCInfo* ipc, base::string16* name) {
|
| + const wchar_t* port_name = name->c_str();
|
| + CountedParameterSet<NameBased> params;
|
| + params[NameBased::NAME] = ParamPickerMake(port_name);
|
| +
|
| + EvalResult result = policy_base_->EvalPolicy(IPC_NTCONNECTALPCPORT_TAG,
|
| + params.GetBase());
|
| + HANDLE handle = NULL;
|
| + (void) handle;
|
| + (void) result;
|
| +
|
| + HMODULE ntdll = GetModuleHandle(L"ntdll.dll");
|
| + NtAlpcConnectPortFunction lpc_connect =
|
| + reinterpret_cast<NtAlpcConnectPortFunction>(::GetProcAddress(
|
| + ntdll, "NtAlpcConnectPort"));
|
| + if (!lpc_connect) {
|
| + ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
|
| + return false;
|
| + }
|
| +
|
| + RtlInitUnicodeStringFunction RtlInitUnicodeString =
|
| + reinterpret_cast<RtlInitUnicodeStringFunction>(
|
| + GetProcAddress(ntdll, "RtlInitUnicodeString"));
|
| + DCHECK(RtlInitUnicodeString);
|
| + UNICODE_STRING uni_name = {0};
|
| + RtlInitUnicodeString(&uni_name, port_name);
|
| + LARGE_INTEGER timeout = {0};
|
| + timeout.QuadPart = -5000000;
|
| +
|
| + ALPC_PORT_ATTRIBUTES port_attributes = {0};
|
| + port_attributes.flags = 0xb0000;
|
| + port_attributes.qos.Length = 0xc;
|
| + port_attributes.qos.ImpersonationLevel = SecurityImpersonation;
|
| + port_attributes.qos.ContextTrackingMode = 0x01;
|
| + port_attributes.qos.EffectiveOnly = 0x01;
|
| + port_attributes.max_message_length = 0x7fff;
|
| + port_attributes.dup_object_types = 7;
|
| +
|
| + ipc->return_info.nt_status = lpc_connect(&handle, &uni_name, NULL,
|
| + &port_attributes, 0x20000, NULL, NULL, NULL, NULL, NULL, &timeout);
|
| + if (ipc->return_info.nt_status == STATUS_SUCCESS) {
|
| + HANDLE dup_handle = NULL;
|
| + if (!::DuplicateHandle(::GetCurrentProcess(), handle,
|
| + ipc->client_info->process, &dup_handle, 0, FALSE,
|
| + DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
|
| + ipc->return_info.nt_status = STATUS_ACCESS_DENIED;
|
| + return false;
|
| + }
|
| + ipc->return_info.handle = dup_handle;
|
| + return true;
|
| + }
|
| +#if 0
|
| + // Return operation status on the IPC.
|
| + ipc->return_info.nt_status = SyncPolicy::CreateEventAction(
|
| + result, *ipc->client_info, *name, event_type, initial_state, &handle);
|
| + ipc->return_info.handle = handle;
|
| +#endif
|
| + return false;
|
| +}
|
| +
|
| +} // namespace sandbox
|
|
|