summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/renderer/plugin_channel_host.cc17
-rw-r--r--ipc/ipc_channel_posix.cc8
-rw-r--r--ipc/ipc_channel_posix.h3
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);