diff options
-rw-r--r-- | ipc/BUILD.gn | 2 | ||||
-rw-r--r-- | ipc/attachment_broker_privileged.cc | 29 | ||||
-rw-r--r-- | ipc/attachment_broker_privileged.h | 14 | ||||
-rw-r--r-- | ipc/attachment_broker_privileged_win.cc | 7 | ||||
-rw-r--r-- | ipc/attachment_broker_privileged_win_unittest.cc | 2 | ||||
-rw-r--r-- | ipc/attachment_broker_unprivileged.cc | 18 | ||||
-rw-r--r-- | ipc/attachment_broker_unprivileged.h | 6 | ||||
-rw-r--r-- | ipc/ipc.gypi | 2 | ||||
-rw-r--r-- | ipc/ipc_channel.h | 28 | ||||
-rw-r--r-- | ipc/ipc_channel_proxy.cc | 14 | ||||
-rw-r--r-- | ipc/ipc_channel_proxy.h | 11 | ||||
-rw-r--r-- | ipc/ipc_endpoint.cc | 18 | ||||
-rw-r--r-- | ipc/ipc_endpoint.h | 52 |
13 files changed, 123 insertions, 80 deletions
diff --git a/ipc/BUILD.gn b/ipc/BUILD.gn index c56559f..eb59274 100644 --- a/ipc/BUILD.gn +++ b/ipc/BUILD.gn @@ -38,6 +38,8 @@ component("ipc") { "ipc_channel_win.cc", "ipc_channel_win.h", "ipc_descriptors.h", + "ipc_endpoint.cc", + "ipc_endpoint.h", "ipc_export.h", "ipc_handle_win.cc", "ipc_handle_win.h", diff --git a/ipc/attachment_broker_privileged.cc b/ipc/attachment_broker_privileged.cc index 1fe3a75..da62ac0 100644 --- a/ipc/attachment_broker_privileged.cc +++ b/ipc/attachment_broker_privileged.cc @@ -6,7 +6,7 @@ #include <algorithm> -#include "ipc/ipc_channel.h" +#include "ipc/ipc_endpoint.h" namespace IPC { @@ -15,25 +15,24 @@ AttachmentBrokerPrivileged::AttachmentBrokerPrivileged() {} AttachmentBrokerPrivileged::~AttachmentBrokerPrivileged() {} void AttachmentBrokerPrivileged::RegisterCommunicationChannel( - Channel* channel) { - channel->set_attachment_broker_endpoint(true); - auto it = std::find(channels_.begin(), channels_.end(), channel); - DCHECK(channels_.end() == it); - channels_.push_back(channel); + Endpoint* endpoint) { + endpoint->SetAttachmentBrokerEndpoint(true); + auto it = std::find(endpoints_.begin(), endpoints_.end(), endpoint); + DCHECK(endpoints_.end() == it); + endpoints_.push_back(endpoint); } void AttachmentBrokerPrivileged::DeregisterCommunicationChannel( - Channel* channel) { - auto it = std::find(channels_.begin(), channels_.end(), channel); - if (it != channels_.end()) - channels_.erase(it); + Endpoint* endpoint) { + auto it = std::find(endpoints_.begin(), endpoints_.end(), endpoint); + if (it != endpoints_.end()) + endpoints_.erase(it); } -Channel* AttachmentBrokerPrivileged::GetChannelWithProcessId( - base::ProcessId id) { - auto it = std::find_if(channels_.begin(), channels_.end(), - [id](Channel* c) { return c->GetPeerPID() == id; }); - if (it == channels_.end()) +Sender* AttachmentBrokerPrivileged::GetSenderWithProcessId(base::ProcessId id) { + auto it = std::find_if(endpoints_.begin(), endpoints_.end(), + [id](Endpoint* c) { return c->GetPeerPID() == id; }); + if (it == endpoints_.end()) return nullptr; return *it; } diff --git a/ipc/attachment_broker_privileged.h b/ipc/attachment_broker_privileged.h index 52befc4..e8c6755 100644 --- a/ipc/attachment_broker_privileged.h +++ b/ipc/attachment_broker_privileged.h @@ -12,7 +12,8 @@ namespace IPC { -class Channel; +class Endpoint; +class Sender; // This abstract subclass of AttachmentBroker is intended for use in a // privileged process . When unprivileged processes want to send attachments, @@ -27,15 +28,16 @@ class IPC_EXPORT AttachmentBrokerPrivileged : public IPC::AttachmentBroker { // communicates attachment information with the broker process. In the broker // process, these channels must be registered and deregistered with the // Attachment Broker as they are created and destroyed. - void RegisterCommunicationChannel(Channel* channel); - void DeregisterCommunicationChannel(Channel* channel); + void RegisterCommunicationChannel(Endpoint* endpoint); + void DeregisterCommunicationChannel(Endpoint* endpoint); protected: - // Returns nullptr if no channel is found. - Channel* GetChannelWithProcessId(base::ProcessId id); + // Returns the sender whose peer's process id is |id|. + // Returns nullptr if no sender is found. + Sender* GetSenderWithProcessId(base::ProcessId id); private: - std::vector<Channel*> channels_; + std::vector<Endpoint*> endpoints_; DISALLOW_COPY_AND_ASSIGN(AttachmentBrokerPrivileged); }; diff --git a/ipc/attachment_broker_privileged_win.cc b/ipc/attachment_broker_privileged_win.cc index 5344e20..77584cf 100644 --- a/ipc/attachment_broker_privileged_win.cc +++ b/ipc/attachment_broker_privileged_win.cc @@ -75,8 +75,8 @@ void AttachmentBrokerPrivilegedWin::RouteDuplicatedHandle( // Another process is the destination. base::ProcessId dest = wire_format.destination_process; - Channel* channel = GetChannelWithProcessId(dest); - if (!channel) { + Sender* sender = GetSenderWithProcessId(dest); + if (!sender) { // Assuming that this message was not sent from a malicious process, the // channel endpoint that would have received this message will block // forever. @@ -85,8 +85,7 @@ void AttachmentBrokerPrivilegedWin::RouteDuplicatedHandle( return; } - channel->Send( - new AttachmentBrokerMsg_WinHandleHasBeenDuplicated(wire_format)); + sender->Send(new AttachmentBrokerMsg_WinHandleHasBeenDuplicated(wire_format)); } AttachmentBrokerPrivilegedWin::HandleWireFormat diff --git a/ipc/attachment_broker_privileged_win_unittest.cc b/ipc/attachment_broker_privileged_win_unittest.cc index c4110bd..3df4006 100644 --- a/ipc/attachment_broker_privileged_win_unittest.cc +++ b/ipc/attachment_broker_privileged_win_unittest.cc @@ -280,7 +280,7 @@ TEST_F(IPCAttachmentBrokerPrivilegedWinTest, SendHandleToSelf) { CommonSetUp(); // Technically, the channel is an endpoint, but we need the proxy listener to // receive the messages so that it can quit the message loop. - channel()->set_attachment_broker_endpoint(false); + channel()->SetAttachmentBrokerEndpoint(false); get_proxy_listener()->set_listener(get_broker()); HANDLE h = CreateTempFile(); diff --git a/ipc/attachment_broker_unprivileged.cc b/ipc/attachment_broker_unprivileged.cc index 45aeae8..44125b3 100644 --- a/ipc/attachment_broker_unprivileged.cc +++ b/ipc/attachment_broker_unprivileged.cc @@ -5,7 +5,7 @@ #include "ipc/attachment_broker_unprivileged.h" #include "ipc/ipc_channel.h" -#include "ipc/ipc_channel_proxy.h" +#include "ipc/ipc_endpoint.h" namespace IPC { @@ -15,19 +15,11 @@ AttachmentBrokerUnprivileged::AttachmentBrokerUnprivileged() AttachmentBrokerUnprivileged::~AttachmentBrokerUnprivileged() {} void AttachmentBrokerUnprivileged::DesignateBrokerCommunicationChannel( - IPC::Channel* channel) { - DCHECK(channel); + Endpoint* endpoint) { + DCHECK(endpoint); DCHECK(!sender_); - sender_ = channel; - channel->set_attachment_broker_endpoint(true); -} - -void AttachmentBrokerUnprivileged::DesignateBrokerCommunicationChannel( - IPC::ChannelProxy* proxy) { - DCHECK(proxy); - DCHECK(!sender_); - sender_ = proxy; - proxy->SetAttachmentBrokerEndpoint(true); + sender_ = endpoint; + endpoint->SetAttachmentBrokerEndpoint(true); } } // namespace IPC diff --git a/ipc/attachment_broker_unprivileged.h b/ipc/attachment_broker_unprivileged.h index 96d3d3e..1e1e60e 100644 --- a/ipc/attachment_broker_unprivileged.h +++ b/ipc/attachment_broker_unprivileged.h @@ -10,8 +10,7 @@ namespace IPC { -class Channel; -class ChannelProxy; +class Endpoint; class Sender; // This abstract subclass of AttachmentBroker is intended for use in @@ -23,8 +22,7 @@ class IPC_EXPORT AttachmentBrokerUnprivileged : public IPC::AttachmentBroker { // In each unprivileged process, exactly one channel should be used to // communicate brokerable attachments with the broker process. - void DesignateBrokerCommunicationChannel(IPC::Channel* channel); - void DesignateBrokerCommunicationChannel(IPC::ChannelProxy* proxy); + void DesignateBrokerCommunicationChannel(Endpoint* endpoint); protected: IPC::Sender* get_sender() { return sender_; } diff --git a/ipc/ipc.gypi b/ipc/ipc.gypi index 0ded800..ce9ffda 100644 --- a/ipc/ipc.gypi +++ b/ipc/ipc.gypi @@ -43,6 +43,8 @@ 'ipc_channel_win.cc', 'ipc_channel_win.h', 'ipc_descriptors.h', + 'ipc_endpoint.cc', + 'ipc_endpoint.h', 'ipc_export.h', 'ipc_handle_win.cc', 'ipc_handle_win.h', diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h index a9f70b2..c74d084 100644 --- a/ipc/ipc_channel.h +++ b/ipc/ipc_channel.h @@ -15,8 +15,8 @@ #include "base/files/scoped_file.h" #include "base/process/process.h" #include "ipc/ipc_channel_handle.h" +#include "ipc/ipc_endpoint.h" #include "ipc/ipc_message.h" -#include "ipc/ipc_sender.h" namespace IPC { @@ -40,7 +40,7 @@ class Listener; // the channel with the mode set to one of the NAMED modes. NAMED modes are // currently used by automation and service processes. -class IPC_EXPORT Channel : public Sender { +class IPC_EXPORT Channel : public Endpoint { // Security tests need access to the pipe handle. friend class ChannelTest; @@ -165,7 +165,6 @@ class IPC_EXPORT Channel : public Sender { Listener* listener, AttachmentBroker* broker = nullptr); - Channel() : attachment_broker_endpoint_(false) {} ~Channel() override; // Connect the pipe. On the server side, this will initiate @@ -182,17 +181,6 @@ class IPC_EXPORT Channel : public Sender { // connection and listen for new ones, use ResetToAcceptingConnectionState. virtual void Close() = 0; - // Get the process ID for the connected peer. - // - // Returns base::kNullProcessId if the peer is not connected yet. Watch out - // for race conditions. You can easily get a channel to another process, but - // if your process has not yet processed the "hello" message from the remote - // side, this will fail. You should either make sure calling this is either - // in response to a message from the remote side (which guarantees that it's - // been connected), or you wait for the "connected" notification on the - // listener. - virtual base::ProcessId GetPeerPID() const = 0; - // Get its own process id. This value is told to the peer. virtual base::ProcessId GetSelfPID() const = 0; @@ -252,18 +240,6 @@ class IPC_EXPORT Channel : public Sender { // process such that it acts similar to if it was exec'd, for tests. static void NotifyProcessForkedForTesting(); #endif - - void set_attachment_broker_endpoint(bool is_endpoint) { - attachment_broker_endpoint_ = is_endpoint; - } - - protected: - bool is_attachment_broker_endpoint() { return attachment_broker_endpoint_; } - - private: - // Whether this channel is used as an endpoint for sending and receiving - // brokerable attachment messages to/from the broker process. - bool attachment_broker_endpoint_; }; #if defined(OS_POSIX) diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index 2398b51..5a9c3e3 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc @@ -59,7 +59,7 @@ void ChannelProxy::Context::CreateChannel(scoped_ptr<ChannelFactory> factory) { channel_id_ = factory->GetName(); channel_ = factory->BuildChannel(this); channel_send_thread_safe_ = channel_->IsSendThreadSafe(); - channel_->set_attachment_broker_endpoint(attachment_broker_endpoint_); + channel_->SetAttachmentBrokerEndpoint(attachment_broker_endpoint_); } bool ChannelProxy::Context::TryFilters(const Message& message) { @@ -489,6 +489,14 @@ void ChannelProxy::ClearIPCTaskRunner() { context()->ClearIPCTaskRunner(); } +base::ProcessId ChannelProxy::GetPeerPID() const { + return context_->peer_pid_; +} + +void ChannelProxy::OnSetAttachmentBrokerEndpoint() { + context()->set_attachment_broker_endpoint(is_attachment_broker_endpoint()); +} + #if defined(OS_POSIX) && !defined(OS_NACL_SFI) // See the TODO regarding lazy initialization of the channel in // ChannelProxy::Init(). @@ -511,10 +519,6 @@ base::ScopedFD ChannelProxy::TakeClientFileDescriptor() { } #endif -void ChannelProxy::SetAttachmentBrokerEndpoint(bool is_endpoint) { - context()->set_attachment_broker_endpoint(is_endpoint); -} - void ChannelProxy::OnChannelInit() { } diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index b01ccbc..714bafd 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h @@ -13,6 +13,7 @@ #include "base/threading/non_thread_safe.h" #include "ipc/ipc_channel.h" #include "ipc/ipc_channel_handle.h" +#include "ipc/ipc_endpoint.h" #include "ipc/ipc_listener.h" #include "ipc/ipc_sender.h" @@ -63,7 +64,7 @@ class SendCallbackHelper; // |channel_lifetime_lock_| is used to protect it. The locking overhead is only // paid if the underlying channel supports thread-safe |Send|. // -class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { +class IPC_EXPORT ChannelProxy : public Endpoint, public base::NonThreadSafe { public: #if defined(ENABLE_IPC_FUZZER) // Interface for a filter to be imposed on outgoing messages which can @@ -147,9 +148,9 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { // Called to clear the pointer to the IPC task runner when it's going away. void ClearIPCTaskRunner(); - // Get the process ID for the connected peer. - // Returns base::kNullProcessId if the peer is not connected yet. - base::ProcessId GetPeerPID() const { return context_->peer_pid_; } + // Endpoint overrides. + base::ProcessId GetPeerPID() const override; + void OnSetAttachmentBrokerEndpoint() override; #if defined(OS_POSIX) && !defined(OS_NACL_SFI) // Calls through to the underlying channel's methods. @@ -157,8 +158,6 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { base::ScopedFD TakeClientFileDescriptor(); #endif - void SetAttachmentBrokerEndpoint(bool is_endpoint); - protected: class Context; // A subclass uses this constructor if it needs to add more information diff --git a/ipc/ipc_endpoint.cc b/ipc/ipc_endpoint.cc new file mode 100644 index 0000000..f613df2 --- /dev/null +++ b/ipc/ipc_endpoint.cc @@ -0,0 +1,18 @@ +// 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/ipc_endpoint.h" + +namespace IPC { + +Endpoint::Endpoint() : attachment_broker_endpoint_(false) {} + +void Endpoint::SetAttachmentBrokerEndpoint(bool is_endpoint) { + if (is_endpoint != attachment_broker_endpoint_) { + attachment_broker_endpoint_ = is_endpoint; + OnSetAttachmentBrokerEndpoint(); + } +} + +} // namespace IPC diff --git a/ipc/ipc_endpoint.h b/ipc/ipc_endpoint.h new file mode 100644 index 0000000..2ace1fe --- /dev/null +++ b/ipc/ipc_endpoint.h @@ -0,0 +1,52 @@ +// 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. + +#ifndef IPC_IPC_ENDPOINT_H_ +#define IPC_IPC_ENDPOINT_H_ + +#include "base/process/process_handle.h" +#include "ipc/ipc_export.h" +#include "ipc/ipc_sender.h" + +namespace IPC { + +// An Endpoint is an abstract base class whose interface provides sending +// functionality, and some receiving functionality. It mostly exists to provide +// a common interface to Channel and ProxyChannel. +class IPC_EXPORT Endpoint : public Sender { + public: + Endpoint(); + ~Endpoint() override {} + + // Get the process ID for the connected peer. + // + // Returns base::kNullProcessId if the peer is not connected yet. Watch out + // for race conditions. You can easily get a channel to another process, but + // if your process has not yet processed the "hello" message from the remote + // side, this will fail. You should either make sure calling this is either + // in response to a message from the remote side (which guarantees that it's + // been connected), or you wait for the "connected" notification on the + // listener. + virtual base::ProcessId GetPeerPID() const = 0; + + // A callback that indicates that is_attachment_broker_endpoint() has been + // changed. + virtual void OnSetAttachmentBrokerEndpoint(){}; + + // Whether this channel is used as an endpoint for sending and receiving + // brokerable attachment messages to/from the broker process. + void SetAttachmentBrokerEndpoint(bool is_endpoint); + + protected: + bool is_attachment_broker_endpoint() { return attachment_broker_endpoint_; } + + private: + // Whether this channel is used as an endpoint for sending and receiving + // brokerable attachment messages to/from the broker process. + bool attachment_broker_endpoint_; +}; + +} // namespace IPC + +#endif // IPC_IPC_ENDPOINT_H_ |