diff options
author | erikchen <erikchen@chromium.org> | 2015-07-27 13:28:20 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-07-27 20:29:06 +0000 |
commit | c04ab34c84e272a6bd7234f14bcf9950a346c580 (patch) | |
tree | c860b9dee6015d90bed92cfd0943b1cf23d68cae /ipc/attachment_broker_privileged_win.cc | |
parent | ba53d6dc1d33f3be64defce3e72cf6c0c5cd855a (diff) | |
download | chromium_src-c04ab34c84e272a6bd7234f14bcf9950a346c580.zip chromium_src-c04ab34c84e272a6bd7234f14bcf9950a346c580.tar.gz chromium_src-c04ab34c84e272a6bd7234f14bcf9950a346c580.tar.bz2 |
ipc: Add attachment broker code for the privileged browser process.
No intended behavior change.
This CL adds the class AttachmentBrokerPrivilegedWin, a subclass of
AttachmentBroker intended for use in the privileged browser process on the
Windows platform. No brokerable attachments are made outside of tests, so this
code is not yet active.
This CL consists of several changes:
- The class AttachmentBrokerPrivilegedWin was created.
- Common logic between AttachmentBrokerPrivilegedWin and AttachmentBrokerWin
was moved to AttachmentBroker.
- ChannelWin was given a new member prelim_queue_. This queue is normally
empty, but in some circumstances messages are queued here before being
processed for delivery. See the documentation for a full explanation.
BUG=466437
Review URL: https://codereview.chromium.org/1246103006
Cr-Commit-Position: refs/heads/master@{#340548}
Diffstat (limited to 'ipc/attachment_broker_privileged_win.cc')
-rw-r--r-- | ipc/attachment_broker_privileged_win.cc | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/ipc/attachment_broker_privileged_win.cc b/ipc/attachment_broker_privileged_win.cc new file mode 100644 index 0000000..52918a3 --- /dev/null +++ b/ipc/attachment_broker_privileged_win.cc @@ -0,0 +1,129 @@ +// Copyright 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 "ipc/attachment_broker_privileged_win.h" + +#include <windows.h> + +#include "base/process/process.h" +#include "ipc/attachment_broker_messages.h" +#include "ipc/brokerable_attachment.h" +#include "ipc/handle_attachment_win.h" +#include "ipc/ipc_channel.h" + +namespace IPC { + +AttachmentBrokerPrivilegedWin::AttachmentBrokerPrivilegedWin() {} + +AttachmentBrokerPrivilegedWin::~AttachmentBrokerPrivilegedWin() {} + +bool AttachmentBrokerPrivilegedWin::SendAttachmentToProcess( + const BrokerableAttachment* attachment, + base::ProcessId destination_process) { + switch (attachment->GetBrokerableType()) { + case BrokerableAttachment::WIN_HANDLE: + const internal::HandleAttachmentWin* handle_attachment = + static_cast<const internal::HandleAttachmentWin*>(attachment); + HandleWireFormat wire_format = + handle_attachment->GetWireFormat(destination_process); + HandleWireFormat new_wire_format = + DuplicateWinHandle(wire_format, base::Process::Current().Pid()); + if (new_wire_format.handle == 0) + return false; + RouteDuplicatedHandle(new_wire_format); + return true; + } + return false; +} + +bool AttachmentBrokerPrivilegedWin::OnMessageReceived(const Message& msg) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(AttachmentBrokerPrivilegedWin, msg) + IPC_MESSAGE_HANDLER(AttachmentBrokerMsg_DuplicateWinHandle, + OnDuplicateWinHandle) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void AttachmentBrokerPrivilegedWin::RegisterCommunicationChannel( + Channel* channel) { + auto it = std::find(channels_.begin(), channels_.end(), channel); + DCHECK(channels_.end() == it); + channels_.push_back(channel); +} + +void AttachmentBrokerPrivilegedWin::DeregisterCommunicationChannel( + Channel* channel) { + auto it = std::find(channels_.begin(), channels_.end(), channel); + DCHECK(it != channels_.end()); + channels_.erase(it); +} + +void AttachmentBrokerPrivilegedWin::OnDuplicateWinHandle( + const HandleWireFormat& wire_format, + base::ProcessId source_pid) { + if (wire_format.destination_process == base::kNullProcessId) + return; + + HandleWireFormat new_wire_format = + DuplicateWinHandle(wire_format, source_pid); + RouteDuplicatedHandle(new_wire_format); +} + +void AttachmentBrokerPrivilegedWin::RouteDuplicatedHandle( + const HandleWireFormat& wire_format) { + // This process is the destination. + if (wire_format.destination_process == base::Process::Current().Pid()) { + scoped_refptr<BrokerableAttachment> attachment( + new internal::HandleAttachmentWin(wire_format)); + HandleReceivedAttachment(attachment); + return; + } + + // Another process is the destination. + base::ProcessId dest = wire_format.destination_process; + auto it = + std::find_if(channels_.begin(), channels_.end(), + [dest](Channel* c) { return c->GetPeerPID() == dest; }); + if (it == channels_.end()) { + // Assuming that this message was not sent from a malicious process, the + // channel endpoint that would have received this message will block + // forever. + LOG(ERROR) << "Failed to deliver brokerable attachment to process with id: " + << dest; + return; + } + + (*it)->Send(new AttachmentBrokerMsg_WinHandleHasBeenDuplicated(wire_format)); +} + +AttachmentBrokerPrivilegedWin::HandleWireFormat +AttachmentBrokerPrivilegedWin::DuplicateWinHandle( + const HandleWireFormat& wire_format, + base::ProcessId source_pid) { + HandleWireFormat new_wire_format; + new_wire_format.destination_process = wire_format.destination_process; + new_wire_format.attachment_id = wire_format.attachment_id; + + HANDLE original_handle = LongToHandle(wire_format.handle); + + base::Process source_process = + base::Process::OpenWithExtraPrivileges(source_pid); + base::Process dest_process = + base::Process::OpenWithExtraPrivileges(wire_format.destination_process); + if (source_process.Handle() && dest_process.Handle()) { + HANDLE new_handle; + DWORD result = ::DuplicateHandle(source_process.Handle(), original_handle, + dest_process.Handle(), &new_handle, 0, + FALSE, DUPLICATE_SAME_ACCESS); + + new_wire_format.handle = (result != 0) ? HandleToLong(new_handle) : 0; + } else { + new_wire_format.handle = 0; + } + return new_wire_format; +} + +} // namespace IPC |