diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 23:06:07 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-15 23:06:07 +0000 |
commit | ef2f6ba19e773ea58b8d6b26ea80bcf6c357ea7d (patch) | |
tree | f18f441d80b4b05ad3e6bcde476fd6461e00742e /ipc | |
parent | 5a05b1de6bb31e66f570b320b6b507e0e2d5798b (diff) | |
download | chromium_src-ef2f6ba19e773ea58b8d6b26ea80bcf6c357ea7d.zip chromium_src-ef2f6ba19e773ea58b8d6b26ea80bcf6c357ea7d.tar.gz chromium_src-ef2f6ba19e773ea58b8d6b26ea80bcf6c357ea7d.tar.bz2 |
Ensure that any IPC sent from a child process that couldn't be deserialized causes that process to be killed.
Today we do this only for a subset of IPCs and not all process types.
R=jar@chromium.org, tsepez@chromium.org
Review URL: https://codereview.chromium.org/283313002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@270839 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_channel_proxy.cc | 12 | ||||
-rw-r--r-- | ipc/ipc_channel_proxy.h | 1 | ||||
-rw-r--r-- | ipc/ipc_channel_reader.cc | 2 | ||||
-rw-r--r-- | ipc/ipc_listener.h | 3 | ||||
-rw-r--r-- | ipc/ipc_message.cc | 11 | ||||
-rw-r--r-- | ipc/ipc_message.h | 13 | ||||
-rw-r--r-- | ipc/ipc_message_macros.h | 4 |
7 files changed, 40 insertions, 6 deletions
diff --git a/ipc/ipc_channel_proxy.cc b/ipc/ipc_channel_proxy.cc index 5c4d743..7e32018 100644 --- a/ipc/ipc_channel_proxy.cc +++ b/ipc/ipc_channel_proxy.cc @@ -64,6 +64,10 @@ bool ChannelProxy::Context::TryFilters(const Message& message) { #endif if (message_filter_router_->TryFilters(message)) { + if (message.dispatch_error()) { + listener_task_runner_->PostTask( + FROM_HERE, base::Bind(&Context::OnDispatchBadMessage, this, message)); + } #ifdef IPC_MESSAGE_LOG_ENABLED if (logger->Enabled()) logger->OnPostDispatchMessage(message, channel_id_); @@ -267,6 +271,8 @@ void ChannelProxy::Context::OnDispatchMessage(const Message& message) { #endif listener_->OnMessageReceived(message); + if (message.dispatch_error()) + listener_->OnBadMessageReceived(message); #ifdef IPC_MESSAGE_LOG_ENABLED if (logger->Enabled()) @@ -290,6 +296,12 @@ void ChannelProxy::Context::OnDispatchError() { listener_->OnChannelError(); } +// Called on the listener's thread +void ChannelProxy::Context::OnDispatchBadMessage(const Message& message) { + if (listener_) + listener_->OnBadMessageReceived(message); +} + //----------------------------------------------------------------------------- ChannelProxy::ChannelProxy(const IPC::ChannelHandle& channel_handle, diff --git a/ipc/ipc_channel_proxy.h b/ipc/ipc_channel_proxy.h index 375a42b..0a3a5d2 100644 --- a/ipc/ipc_channel_proxy.h +++ b/ipc/ipc_channel_proxy.h @@ -180,6 +180,7 @@ class IPC_EXPORT ChannelProxy : public Sender, public base::NonThreadSafe { void AddFilter(MessageFilter* filter); void OnDispatchConnected(); void OnDispatchError(); + void OnDispatchBadMessage(const Message& message); scoped_refptr<base::SingleThreadTaskRunner> listener_task_runner_; Listener* listener_; diff --git a/ipc/ipc_channel_reader.cc b/ipc/ipc_channel_reader.cc index 401e4e1..9a3cc3c 100644 --- a/ipc/ipc_channel_reader.cc +++ b/ipc/ipc_channel_reader.cc @@ -95,6 +95,8 @@ bool ChannelReader::DispatchInputData(const char* input_data, HandleInternalMessage(m); else listener_->OnMessageReceived(m); + if (m.dispatch_error()) + listener_->OnBadMessageReceived(m); p = message_tail; } else { // Last message is partial. diff --git a/ipc/ipc_listener.h b/ipc/ipc_listener.h index 9189eec..733bc46 100644 --- a/ipc/ipc_listener.h +++ b/ipc/ipc_listener.h @@ -28,6 +28,9 @@ class IPC_EXPORT Listener { // This method is not called when a channel is closed normally. virtual void OnChannelError() {} + // Called when a message's deserialization failed. + virtual void OnBadMessageReceived(const Message& message) {} + #if defined(OS_POSIX) // Called on the server side when a channel that listens for connections // denies an attempt to connect. diff --git a/ipc/ipc_message.cc b/ipc/ipc_message.cc index f7fe827..1ac4d6e 100644 --- a/ipc/ipc_message.cc +++ b/ipc/ipc_message.cc @@ -47,7 +47,7 @@ Message::Message() header()->num_fds = 0; header()->pad = 0; #endif - InitLoggingVariables(); + Init(); } Message::Message(int32 routing_id, uint32 type, PriorityValue priority) @@ -60,21 +60,22 @@ Message::Message(int32 routing_id, uint32 type, PriorityValue priority) header()->num_fds = 0; header()->pad = 0; #endif - InitLoggingVariables(); + Init(); } Message::Message(const char* data, int data_len) : Pickle(data, data_len) { - InitLoggingVariables(); + Init(); } Message::Message(const Message& other) : Pickle(other) { - InitLoggingVariables(); + Init(); #if defined(OS_POSIX) file_descriptor_set_ = other.file_descriptor_set_; #endif } -void Message::InitLoggingVariables() { +void Message::Init() { + dispatch_error_ = false; #ifdef IPC_MESSAGE_LOG_ENABLED received_time_ = 0; dont_log_ = false; diff --git a/ipc/ipc_message.h b/ipc/ipc_message.h index ea6cda6..e4b6208 100644 --- a/ipc/ipc_message.h +++ b/ipc/ipc_message.h @@ -121,6 +121,14 @@ class IPC_EXPORT Message : public Pickle { return (header()->flags & PUMPING_MSGS_BIT) != 0; } + void set_dispatch_error() const { + dispatch_error_ = true; + } + + bool dispatch_error() const { + return dispatch_error_; + } + uint32 type() const { return header()->type; } @@ -236,7 +244,10 @@ class IPC_EXPORT Message : public Pickle { return headerT<Header>(); } - void InitLoggingVariables(); + void Init(); + + // Used internally to support IPC::Listener::OnBadMessageReceived. + mutable bool dispatch_error_; #if defined(OS_POSIX) // The set of file descriptors associated with this message. diff --git a/ipc/ipc_message_macros.h b/ipc/ipc_message_macros.h index d5ffff7..5bc1ad4 100644 --- a/ipc/ipc_message_macros.h +++ b/ipc/ipc_message_macros.h @@ -933,6 +933,8 @@ TRACK_RUN_IN_IPC_HANDLER(member_func); \ msg_is_ok__ = msg_class::Dispatch(&ipc_message__, obj, this, \ param__, &member_func); \ + if (!msg_is_ok__) \ + ipc_message__.set_dispatch_error(); \ } \ break; @@ -944,6 +946,8 @@ TRACK_RUN_IN_IPC_HANDLER(member_func); \ msg_is_ok__ = msg_class::DispatchDelayReply(&ipc_message__, obj, \ param__, &member_func); \ + if (!msg_is_ok__) \ + ipc_message__.set_dispatch_error(); \ } \ break; |