diff options
-rw-r--r-- | chrome/renderer/plugin_channel_host.cc | 17 | ||||
-rw-r--r-- | ipc/ipc_channel_posix.cc | 8 | ||||
-rw-r--r-- | ipc/ipc_channel_posix.h | 3 |
3 files changed, 27 insertions, 1 deletions
diff --git a/chrome/renderer/plugin_channel_host.cc b/chrome/renderer/plugin_channel_host.cc index 7dfb3b7..bddf69f 100644 --- a/chrome/renderer/plugin_channel_host.cc +++ b/chrome/renderer/plugin_channel_host.cc @@ -7,6 +7,10 @@ #include "chrome/common/plugin_messages.h" #include "chrome/plugin/npobject_base.h" +#if defined(OS_POSIX) +#include "ipc/ipc_channel_posix.h" +#endif + #include "third_party/WebKit/WebKit/chromium/public/WebBindings.h" // A simple MessageFilter that will ignore all messages and respond to sync @@ -83,6 +87,19 @@ PluginChannelHost::~PluginChannelHost() { bool PluginChannelHost::Init(MessageLoop* ipc_message_loop, bool create_pipe_now) { +#if defined(OS_POSIX) + if (!IPC::ChannelSocketExists(channel_name())) { + // Attempting to use this IPC channel would result in a crash + // inside IPC code within the PluginChannelBase::Init call. The plugin + // channel in the plugin process is supposed to have created this channel + // and sent it to this process, the renderer process. If this channel + // closes and is removed, it cannot be reused until the plugin process + // recreates it. + LOG(ERROR) << "Refusing use of missing IPC channel " << channel_name(); + return false; + } +#endif + bool ret = PluginChannelBase::Init(ipc_message_loop, create_pipe_now); is_listening_filter_ = new IsListeningFilter; channel_->AddFilter(is_listening_filter_); diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc index 545ad0c..f6b19f7 100644 --- a/ipc/ipc_channel_posix.cc +++ b/ipc/ipc_channel_posix.cc @@ -299,6 +299,11 @@ void RemoveAndCloseChannelSocket(const std::string& name) { } // static +bool ChannelSocketExists(const std::string& name) { + return Singleton<PipeMap>()->Lookup(name) != -1; +} + +// static bool SocketPair(int* fd1, int* fd2) { int pipe_fds[2]; if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) { @@ -362,7 +367,8 @@ bool Channel::ChannelImpl::CreatePipe(const std::string& channel_id, // initial channel must not be recycled here. http://crbug.com/26754. static bool used_initial_channel = false; if (used_initial_channel) { - LOG(FATAL) << "Denying attempt to reuse initial IPC channel"; + LOG(FATAL) << "Denying attempt to reuse initial IPC channel for " + << pipe_name_; return false; } used_initial_channel = true; diff --git a/ipc/ipc_channel_posix.h b/ipc/ipc_channel_posix.h index 714b150..dd45345 100644 --- a/ipc/ipc_channel_posix.h +++ b/ipc/ipc_channel_posix.h @@ -26,6 +26,9 @@ void AddChannelSocket(const std::string& name, int socket); // Remove the channel name mapping, and close the corresponding socket. void RemoveAndCloseChannelSocket(const std::string& name); +// Returns true if a channel named |name| is available. +bool ChannelSocketExists(const std::string& name); + // Construct a socket pair appropriate for IPC: UNIX domain, nonblocking. // Returns false on error. bool SocketPair(int* fd1, int* fd2); |