diff options
| author | nick <nick@chromium.org> | 2015-06-02 16:23:31 -0700 | 
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2015-06-02 23:24:00 +0000 | 
| commit | 167948263fa1c560de096b877be8a151cfed3ff7 (patch) | |
| tree | d808c7380b5b640087f08c8f40a2b8732456b6e2 | |
| parent | 317862043e80cfd60e81aaeb2d5d028fb65d87a2 (diff) | |
| download | chromium_src-167948263fa1c560de096b877be8a151cfed3ff7.zip chromium_src-167948263fa1c560de096b877be8a151cfed3ff7.tar.gz chromium_src-167948263fa1c560de096b877be8a151cfed3ff7.tar.bz2 | |
Introduce bad_message.h for chrome and NaCl.
Where needed, add variants of bad_message::ReceivedBadMessage that take a
BrowserMessageFilter instead of a RenderProcessHost.
Rename BrowserMessageFilter::BadMessageReceived to be ::ShutdownForBadMessage. It's now only called from the bad_message helper functions after logging the error to UMA.
Use the new bad_message helpers in all places that previously called BrowserMessageFilter::BadMessageReceived().
BUG=None
TEST=None
Review URL: https://codereview.chromium.org/1145013004
Cr-Commit-Position: refs/heads/master@{#332488}
32 files changed, 454 insertions, 104 deletions
| diff --git a/chrome/browser/bad_message.cc b/chrome/browser/bad_message.cc new file mode 100644 index 0000000..81a4469 --- /dev/null +++ b/chrome/browser/bad_message.cc @@ -0,0 +1,36 @@ +// 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 "chrome/browser/bad_message.h" + +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "content/public/browser/browser_message_filter.h" +#include "content/public/browser/render_process_host.h" + +namespace bad_message { + +namespace { + +void LogBadMessage(BadMessageReason reason) { +  LOG(ERROR) << "Terminating renderer for bad IPC message, reason " << reason; +  UMA_HISTOGRAM_ENUMERATION("Stability.BadMessageTerminated.Chrome", reason, +                            BAD_MESSAGE_MAX); +} + +}  // namespace + +void ReceivedBadMessage(content::RenderProcessHost* host, +                        BadMessageReason reason) { +  LogBadMessage(reason); +  host->ShutdownForBadMessage(); +} + +void ReceivedBadMessage(content::BrowserMessageFilter* filter, +                        BadMessageReason reason) { +  LogBadMessage(reason); +  filter->ShutdownForBadMessage(); +} + +}  // namespace bad_message diff --git a/chrome/browser/bad_message.h b/chrome/browser/bad_message.h new file mode 100644 index 0000000..0707894 --- /dev/null +++ b/chrome/browser/bad_message.h @@ -0,0 +1,46 @@ +// 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 CHROME_BROWSER_BAD_MESSAGE_H_ +#define CHROME_BROWSER_BAD_MESSAGE_H_ + +namespace content { +class BrowserMessageFilter; +class RenderProcessHost; +} + +namespace bad_message { + +// The browser process often chooses to terminate a renderer if it receives +// a bad IPC message. The reasons are tracked for metrics. +// +// See also content/browser/bad_message.h. +// +// NOTE: Do not remove or reorder elements in this list. Add new entries at the +// end. Items may be renamed but do not change the values. We rely on the enum +// values in histograms. Also update histograms.xml with any new values. +enum BadMessageReason { +  WRLHH_LOGGING_STOPPED_BAD_STATE = 0, + +  // Please add new elements here. The naming convention is abbreviated class +  // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the +  // reason. +  BAD_MESSAGE_MAX +}; + +// Called when the browser receives a bad IPC message from a renderer process on +// the UI thread. Logs the event, records a histogram metric for the |reason|, +// and terminates the process for |host|. +void ReceivedBadMessage(content::RenderProcessHost* host, +                        BadMessageReason reason); + +// Called when a browser message filter receives a bad IPC message from a +// renderer or other child process. Logs the event, records a histogram metric +// for the |reason|, and terminates the process for |filter|. +void ReceivedBadMessage(content::BrowserMessageFilter* filter, +                        BadMessageReason reason); + +}  // namespace bad_message + +#endif  // CHROME_BROWSER_BAD_MESSAGE_H_ diff --git a/chrome/browser/devtools/devtools_ui_bindings.cc b/chrome/browser/devtools/devtools_ui_bindings.cc index 79a534d..3722001 100644 --- a/chrome/browser/devtools/devtools_ui_bindings.cc +++ b/chrome/browser/devtools/devtools_ui_bindings.cc @@ -775,6 +775,7 @@ void DevToolsUIBindings::RecordEnumeratedHistogram(const std::string& name,                                                     int boundary_value) {    if (!(boundary_value >= 0 && boundary_value <= 100 && sample >= 0 &&          sample < boundary_value)) { +    // TODO(nick): Replace with chrome::bad_message::ReceivedBadMessage().      frontend_host_->BadMessageRecieved();      return;    } diff --git a/chrome/browser/media/webrtc_logging_handler_host.cc b/chrome/browser/media/webrtc_logging_handler_host.cc index 5c1476b..d563727 100644 --- a/chrome/browser/media/webrtc_logging_handler_host.cc +++ b/chrome/browser/media/webrtc_logging_handler_host.cc @@ -15,6 +15,7 @@  #include "base/strings/string_number_conversions.h"  #include "base/sys_info.h"  #include "base/time/time.h" +#include "chrome/browser/bad_message.h"  #include "chrome/browser/browser_process.h"  #include "chrome/browser/chromeos/settings/cros_settings.h"  #include "chrome/browser/media/webrtc_log_list.h" @@ -489,7 +490,8 @@ void WebRtcLoggingHandlerHost::OnLoggingStoppedInRenderer() {      // and must not be invoked.      DLOG(ERROR) << "OnLoggingStoppedInRenderer invoked in state "                  << logging_state_; -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::WRLHH_LOGGING_STOPPED_BAD_STATE);      return;    }    logging_started_time_ = base::Time(); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 5ff7380..ff7539d 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -236,6 +236,8 @@        'browser/autofill/risk_util.h',        'browser/autofill/validation_rules_storage_factory.cc',        'browser/autofill/validation_rules_storage_factory.h', +      'browser/bad_message.cc', +      'browser/bad_message.h',        'browser/banners/app_banner_data_fetcher.cc',        'browser/banners/app_banner_data_fetcher.h',        'browser/banners/app_banner_debug_log.cc', diff --git a/components/nacl.gyp b/components/nacl.gyp index 9c8e2b3..cc733fd 100644 --- a/components/nacl.gyp +++ b/components/nacl.gyp @@ -90,6 +90,8 @@            'target_name': 'nacl_browser',            'type': 'static_library',            'sources': [ +            'nacl/browser/bad_message.cc', +            'nacl/browser/bad_message.h',              'nacl/browser/nacl_broker_host_win.cc',              'nacl/browser/nacl_broker_host_win.h',              'nacl/browser/nacl_broker_service_win.cc', diff --git a/components/nacl/BUILD.gn b/components/nacl/BUILD.gn index 5576df1..31da13d 100644 --- a/components/nacl/BUILD.gn +++ b/components/nacl/BUILD.gn @@ -56,6 +56,8 @@ if (enable_nacl) {    source_set("nacl_browser") {      sources = [ +      "browser/bad_message.cc", +      "browser/bad_message.h",        "browser/nacl_broker_host_win.cc",        "browser/nacl_broker_host_win.h",        "browser/nacl_broker_service_win.cc", diff --git a/components/nacl/browser/bad_message.cc b/components/nacl/browser/bad_message.cc new file mode 100644 index 0000000..1803697 --- /dev/null +++ b/components/nacl/browser/bad_message.cc @@ -0,0 +1,23 @@ +// 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 "components/nacl/browser/bad_message.h" + +#include "base/logging.h" +#include "base/metrics/histogram_macros.h" +#include "content/public/browser/browser_message_filter.h" + +namespace nacl { +namespace bad_message { + +void ReceivedBadMessage(content::BrowserMessageFilter* filter, +                        BadMessageReason reason) { +  LOG(ERROR) << "Terminating renderer for bad IPC message, reason " << reason; +  UMA_HISTOGRAM_ENUMERATION("Stability.BadMessageTerminated.NaCl", reason, +                            BAD_MESSAGE_MAX); +  filter->ShutdownForBadMessage(); +} + +}  // namespace bad_message +}  // namespace nacl diff --git a/components/nacl/browser/bad_message.h b/components/nacl/browser/bad_message.h new file mode 100644 index 0000000..e8c1ac9 --- /dev/null +++ b/components/nacl/browser/bad_message.h @@ -0,0 +1,43 @@ +// 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 COMPONENTS_NACL_BROWSER_BAD_MESSAGE_H_ +#define COMPONENTS_NACL_BROWSER_BAD_MESSAGE_H_ + +namespace content { +class BrowserMessageFilter; +} + +namespace nacl { +namespace bad_message { + +// The browser process often chooses to terminate a renderer if it receives +// a bad IPC message. The reasons are tracked for metrics. +// +// See also content/browser/bad_message.h. +// +// NOTE: Do not remove or reorder elements in this list. Add new entries at the +// end. Items may be renamed but do not change the values. We rely on the enum +// values in histograms. Also update histograms.xml with any new values. +enum BadMessageReason { +  NFH_OPEN_EXECUTABLE_BAD_ROUTING_ID = 0, +  NHMF_LAUNCH_CONTINUATION_BAD_ROUTING_ID = 1, +  NHMF_GET_NEXE_FD_BAD_URL = 2, + +  // Please add new elements here. The naming convention is abbreviated class +  // name (e.g. NaclHostMessageFilter becomes NHMF) plus a unique description of +  // the reason. +  BAD_MESSAGE_MAX +}; + +// Called when a browser message filter receives a bad IPC message from a +// renderer or other child process. Logs the event, records a histogram metric +// for the |reason|, and terminates the process for |filter|. +void ReceivedBadMessage(content::BrowserMessageFilter* filter, +                        BadMessageReason reason); + +}  // namespace bad_message +}  // namespace nacl + +#endif  // COMPONENTS_NACL_BROWSER_BAD_MESSAGE_H_ diff --git a/components/nacl/browser/nacl_file_host.cc b/components/nacl/browser/nacl_file_host.cc index f384910..51c29c5 100644 --- a/components/nacl/browser/nacl_file_host.cc +++ b/components/nacl/browser/nacl_file_host.cc @@ -10,6 +10,7 @@  #include "base/files/file_util.h"  #include "base/strings/utf_string_conversions.h"  #include "base/threading/sequenced_worker_pool.h" +#include "components/nacl/browser/bad_message.h"  #include "components/nacl/browser/nacl_browser.h"  #include "components/nacl/browser/nacl_browser_delegate.h"  #include "components/nacl/browser/nacl_host_message_filter.h" @@ -248,7 +249,10 @@ void OpenNaClExecutable(    content::RenderViewHost* rvh = content::RenderViewHost::FromID(        nacl_host_message_filter->render_process_id(), render_view_id);    if (!rvh) { -    nacl_host_message_filter->BadMessageReceived();  // Kill the renderer. +    nacl::bad_message::ReceivedBadMessage( +        nacl_host_message_filter.get(), +        nacl::bad_message::NFH_OPEN_EXECUTABLE_BAD_ROUTING_ID); +    delete reply_msg;      return;    }    content::SiteInstance* site_instance = rvh->GetSiteInstance(); diff --git a/components/nacl/browser/nacl_host_message_filter.cc b/components/nacl/browser/nacl_host_message_filter.cc index 8ebfed4..d781159 100644 --- a/components/nacl/browser/nacl_host_message_filter.cc +++ b/components/nacl/browser/nacl_host_message_filter.cc @@ -5,6 +5,7 @@  #include "components/nacl/browser/nacl_host_message_filter.h"  #include "base/sys_info.h" +#include "components/nacl/browser/bad_message.h"  #include "components/nacl/browser/nacl_browser.h"  #include "components/nacl/browser/nacl_file_host.h"  #include "components/nacl/browser/nacl_process_host.h" @@ -156,7 +157,9 @@ void NaClHostMessageFilter::LaunchNaClContinuation(    content::RenderViewHost* rvh = content::RenderViewHost::FromID(        render_process_id(), launch_params.render_view_id);    if (!rvh) { -    BadMessageReceived();  // Kill the renderer. +    bad_message::ReceivedBadMessage( +        this, bad_message::NHMF_LAUNCH_CONTINUATION_BAD_ROUTING_ID); +    delete reply_msg;      return;    } @@ -358,7 +361,8 @@ void NaClHostMessageFilter::OnGetNexeFd(    if (!cache_info.pexe_url.is_valid()) {      LOG(ERROR) << "Bad URL received from GetNexeFd: " <<          cache_info.pexe_url.possibly_invalid_spec(); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::NHMF_GET_NEXE_FD_BAD_URL);      return;    } diff --git a/content/browser/appcache/appcache_dispatcher_host.cc b/content/browser/appcache/appcache_dispatcher_host.cc index eac1eff..e35610f 100644 --- a/content/browser/appcache/appcache_dispatcher_host.cc +++ b/content/browser/appcache/appcache_dispatcher_host.cc @@ -7,6 +7,7 @@  #include "base/bind.h"  #include "base/bind_helpers.h"  #include "content/browser/appcache/chrome_appcache_service.h" +#include "content/browser/bad_message.h"  #include "content/common/appcache_messages.h"  #include "content/public/browser/user_metrics.h" @@ -62,15 +63,10 @@ bool AppCacheDispatcherHost::OnMessageReceived(const IPC::Message& message) {  AppCacheDispatcherHost::~AppCacheDispatcherHost() {} -void AppCacheDispatcherHost::BadMessageReceived() { -  RecordAction(base::UserMetricsAction("BadMessageTerminate_ACDH")); -  BrowserMessageFilter::BadMessageReceived(); -} -  void AppCacheDispatcherHost::OnRegisterHost(int host_id) {    if (appcache_service_.get()) {      if (!backend_impl_.RegisterHost(host_id)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::ACDH_REGISTER);      }    }  } @@ -78,7 +74,7 @@ void AppCacheDispatcherHost::OnRegisterHost(int host_id) {  void AppCacheDispatcherHost::OnUnregisterHost(int host_id) {    if (appcache_service_.get()) {      if (!backend_impl_.UnregisterHost(host_id)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::ACDH_UNREGISTER);      }    }  } @@ -87,7 +83,7 @@ void AppCacheDispatcherHost::OnSetSpawningHostId(      int host_id, int spawning_host_id) {    if (appcache_service_.get()) {      if (!backend_impl_.SetSpawningHostId(host_id, spawning_host_id)) -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::ACDH_SET_SPAWNING);    }  } @@ -100,7 +96,7 @@ void AppCacheDispatcherHost::OnSelectCache(                                     document_url,                                     cache_document_was_loaded_from,                                     opt_manifest_url)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::ACDH_SELECT_CACHE);      }    } else {      frontend_proxy_.OnCacheSelected(host_id, AppCacheInfo()); @@ -112,7 +108,8 @@ void AppCacheDispatcherHost::OnSelectCacheForWorker(    if (appcache_service_.get()) {      if (!backend_impl_.SelectCacheForWorker(              host_id, parent_process_id, parent_host_id)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage( +          this, bad_message::ACDH_SELECT_CACHE_FOR_WORKER);      }    } else {      frontend_proxy_.OnCacheSelected(host_id, AppCacheInfo()); @@ -123,7 +120,8 @@ void AppCacheDispatcherHost::OnSelectCacheForSharedWorker(      int host_id, int64 appcache_id) {    if (appcache_service_.get()) {      if (!backend_impl_.SelectCacheForSharedWorker(host_id, appcache_id)) -      BadMessageReceived(); +      bad_message::ReceivedBadMessage( +          this, bad_message::ACDH_SELECT_CACHE_FOR_SHARED_WORKER);    } else {      frontend_proxy_.OnCacheSelected(host_id, AppCacheInfo());    } @@ -135,7 +133,8 @@ void AppCacheDispatcherHost::OnMarkAsForeignEntry(    if (appcache_service_.get()) {      if (!backend_impl_.MarkAsForeignEntry(              host_id, document_url, cache_document_was_loaded_from)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, +                                      bad_message::ACDH_MARK_AS_FOREIGN_ENTRY);      }    }  } @@ -148,7 +147,8 @@ void AppCacheDispatcherHost::OnGetResourceList(  void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) {    if (pending_reply_msg_) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::ACDH_PENDING_REPLY_IN_GET_STATUS);      delete reply_msg;      return;    } @@ -157,7 +157,7 @@ void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) {    if (appcache_service_.get()) {      if (!backend_impl_.GetStatusWithCallback(              host_id, get_status_callback_, reply_msg)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::ACDH_GET_STATUS);      }      return;    } @@ -168,7 +168,8 @@ void AppCacheDispatcherHost::OnGetStatus(int host_id, IPC::Message* reply_msg) {  void AppCacheDispatcherHost::OnStartUpdate(int host_id,                                             IPC::Message* reply_msg) {    if (pending_reply_msg_) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::ACDH_PENDING_REPLY_IN_START_UPDATE);      delete reply_msg;      return;    } @@ -177,7 +178,7 @@ void AppCacheDispatcherHost::OnStartUpdate(int host_id,    if (appcache_service_.get()) {      if (!backend_impl_.StartUpdateWithCallback(              host_id, start_update_callback_, reply_msg)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::ACDH_START_UPDATE);      }      return;    } @@ -187,7 +188,8 @@ void AppCacheDispatcherHost::OnStartUpdate(int host_id,  void AppCacheDispatcherHost::OnSwapCache(int host_id, IPC::Message* reply_msg) {    if (pending_reply_msg_) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::ACDH_PENDING_REPLY_IN_SWAP_CACHE);      delete reply_msg;      return;    } @@ -196,7 +198,7 @@ void AppCacheDispatcherHost::OnSwapCache(int host_id, IPC::Message* reply_msg) {    if (appcache_service_.get()) {      if (!backend_impl_.SwapCacheWithCallback(              host_id, swap_cache_callback_, reply_msg)) { -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::ACDH_SWAP_CACHE);      }      return;    } diff --git a/content/browser/appcache/appcache_dispatcher_host.h b/content/browser/appcache/appcache_dispatcher_host.h index c0a615e..c9c1cdd 100644 --- a/content/browser/appcache/appcache_dispatcher_host.h +++ b/content/browser/appcache/appcache_dispatcher_host.h @@ -33,9 +33,6 @@ class AppCacheDispatcherHost : public BrowserMessageFilter {   protected:    ~AppCacheDispatcherHost() override; -  // BrowserMessageFilter override. -  void BadMessageReceived() override; -   private:    // IPC message handlers    void OnRegisterHost(int host_id); diff --git a/content/browser/bad_message.cc b/content/browser/bad_message.cc index cc41b00b..975aab1 100644 --- a/content/browser/bad_message.cc +++ b/content/browser/bad_message.cc @@ -6,17 +6,31 @@  #include "base/logging.h"  #include "base/metrics/histogram_macros.h" +#include "content/public/browser/browser_message_filter.h"  #include "content/public/browser/render_process_host.h"  namespace content {  namespace bad_message { -void ReceivedBadMessage(RenderProcessHost* host, BadMessageReason reason) { +namespace { + +void LogBadMessage(BadMessageReason reason) {    LOG(ERROR) << "Terminating renderer for bad IPC message, reason " << reason;    UMA_HISTOGRAM_ENUMERATION("Stability.BadMessageTerminated.Content", reason,                              BAD_MESSAGE_MAX); +} + +}  // namespace + +void ReceivedBadMessage(RenderProcessHost* host, BadMessageReason reason) { +  LogBadMessage(reason);    host->ShutdownForBadMessage();  } +void ReceivedBadMessage(BrowserMessageFilter* filter, BadMessageReason reason) { +  LogBadMessage(reason); +  filter->ShutdownForBadMessage(); +} +  }  // namespace bad_message  }  // namespace content diff --git a/content/browser/bad_message.h b/content/browser/bad_message.h index 337014d..3538aa7 100644 --- a/content/browser/bad_message.h +++ b/content/browser/bad_message.h @@ -6,6 +6,7 @@  #define CONTENT_BROWSER_BAD_MESSAGE_H_  namespace content { +class BrowserMessageFilter;  class RenderProcessHost;  namespace bad_message { @@ -40,17 +41,80 @@ enum BadMessageReason {    RFPH_DETACH = 17,    DFH_BAD_EMBEDDER_MESSAGE = 18,    NC_AUTO_SUBFRAME = 19, +  CSDH_NOT_RECOGNIZED = 20, +  DSMF_OPEN_STORAGE = 21, +  DSMF_LOAD_STORAGE = 22, +  DBMF_INVALID_ORIGIN_ON_OPEN = 23, +  DBMF_DB_NOT_OPEN_ON_MODIFY = 24, +  DBMF_DB_NOT_OPEN_ON_CLOSE = 25, +  DBMF_INVALID_ORIGIN_ON_SQLITE_ERROR = 26, +  RDH_INVALID_PRIORITY = 27, +  RDH_REQUEST_NOT_TRANSFERRING = 28, +  RDH_BAD_DOWNLOAD = 29, +  NMF_NO_PERMISSION_SHOW = 30, +  NMF_NO_PERMISSION_CLOSE = 31, +  NMF_NO_PERMISSION_VERIFY = 32, +  MH_INVALID_MIDI_PORT = 33, +  MH_SYS_EX_PERMISSION = 34, +  ACDH_REGISTER = 35, +  ACDH_UNREGISTER = 36, +  ACDH_SET_SPAWNING = 37, +  ACDH_SELECT_CACHE = 38, +  ACDH_SELECT_CACHE_FOR_WORKER = 39, +  ACDH_SELECT_CACHE_FOR_SHARED_WORKER = 40, +  ACDH_MARK_AS_FOREIGN_ENTRY = 41, +  ACDH_PENDING_REPLY_IN_GET_STATUS = 42, +  ACDH_GET_STATUS = 43, +  ACDH_PENDING_REPLY_IN_START_UPDATE = 44, +  ACDH_START_UPDATE = 45, +  ACDH_PENDING_REPLY_IN_SWAP_CACHE = 46, +  ACDH_SWAP_CACHE = 47, +  SWDH_NOT_HANDLED = 48, +  SWDH_REGISTER_BAD_URL = 49, +  SWDH_REGISTER_NO_HOST = 50, +  SWDH_REGISTER_CANNOT = 51, +  SWDH_UNREGISTER_BAD_URL = 52, +  SWDH_UNREGISTER_NO_HOST = 53, +  SWDH_UNREGISTER_CANNOT = 54, +  SWDH_GET_REGISTRATION_BAD_URL = 55, +  SWDH_GET_REGISTRATION_NO_HOST = 56, +  SWDH_GET_REGISTRATION_CANNOT = 57, +  SWDH_GET_REGISTRATION_FOR_READY_NO_HOST = 58, +  SWDH_GET_REGISTRATION_FOR_READY_ALREADY_IN_PROGRESS = 59, +  SWDH_POST_MESSAGE = 60, +  SWDH_PROVIDER_CREATED_NO_HOST = 61, +  SWDH_PROVIDER_DESTROYED_NO_HOST = 62, +  SWDH_SET_HOSTED_VERSION_NO_HOST = 63, +  SWDH_SET_HOSTED_VERSION = 64, +  SWDH_WORKER_SCRIPT_LOAD_NO_HOST = 65, +  SWDH_INCREMENT_WORKER_BAD_HANDLE = 66, +  SWDH_DECREMENT_WORKER_BAD_HANDLE = 67, +  SWDH_INCREMENT_REGISTRATION_BAD_HANDLE = 68, +  SWDH_DECREMENT_REGISTRATION_BAD_HANDLE = 69, +  SWDH_TERMINATE_BAD_HANDLE = 70, +  FAMF_APPEND_ITEM_TO_BLOB = 71, +  FAMF_APPEND_SHARED_MEMORY_TO_BLOB = 72, +  FAMF_MALFORMED_STREAM_URL = 73, +  FAMF_APPEND_ITEM_TO_STREAM = 74, +  FAMF_APPEND_SHARED_MEMORY_TO_STREAM = 75, +  IDBDH_CAN_READ_FILE = 76, +  IDBDH_GET_OR_TERMINATE = 77,    // Please add new elements here. The naming convention is abbreviated class    // name (e.g. RenderFrameHost becomes RFH) plus a unique description of the    // reason.    BAD_MESSAGE_MAX  }; -// Called when the browser receives a bad IPC message from a renderer process. -// Logs the event, records a histogram metric for the |reason|, and terminates -// the process for |host|. +// Called when the browser receives a bad IPC message from a renderer process on +// the UI thread. Logs the event, records a histogram metric for the |reason|, +// and terminates the process for |host|.  void ReceivedBadMessage(RenderProcessHost* host, BadMessageReason reason); +// Called when a browser message filter receives a bad IPC message from a +// renderer or other child process. Logs the event, records a histogram metric +// for the |reason|, and terminates the process for |filter|. +void ReceivedBadMessage(BrowserMessageFilter* filter, BadMessageReason reason); +  }  // namespace bad_message  }  // namespace content diff --git a/content/browser/cache_storage/cache_storage_dispatcher_host.cc b/content/browser/cache_storage/cache_storage_dispatcher_host.cc index f8630f6..77bc33f 100644 --- a/content/browser/cache_storage/cache_storage_dispatcher_host.cc +++ b/content/browser/cache_storage/cache_storage_dispatcher_host.cc @@ -9,6 +9,7 @@  #include "base/strings/string16.h"  #include "base/strings/utf_string_conversions.h"  #include "base/trace_event/trace_event.h" +#include "content/browser/bad_message.h"  #include "content/browser/cache_storage/cache_storage_cache.h"  #include "content/browser/cache_storage/cache_storage_context_impl.h"  #include "content/browser/cache_storage/cache_storage_manager.h" @@ -87,7 +88,7 @@ bool CacheStorageDispatcherHost::OnMessageReceived(    IPC_END_MESSAGE_MAP()    if (!handled) -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::CSDH_NOT_RECOGNIZED);    return handled;  } diff --git a/content/browser/dom_storage/dom_storage_message_filter.cc b/content/browser/dom_storage/dom_storage_message_filter.cc index ca3bcc5a..e792c29 100644 --- a/content/browser/dom_storage/dom_storage_message_filter.cc +++ b/content/browser/dom_storage/dom_storage_message_filter.cc @@ -9,6 +9,7 @@  #include "base/strings/nullable_string16.h"  #include "base/strings/utf_string_conversions.h"  #include "base/threading/sequenced_worker_pool.h" +#include "content/browser/bad_message.h"  #include "content/browser/dom_storage/dom_storage_area.h"  #include "content/browser/dom_storage/dom_storage_context_wrapper.h"  #include "content/browser/dom_storage/dom_storage_host.h" @@ -91,8 +92,8 @@ void DOMStorageMessageFilter::OnOpenStorageArea(int connection_id,                                                  const GURL& origin) {    DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));    if (!host_->OpenStorageArea(connection_id, namespace_id, origin)) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_DSMF_1")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::DSMF_OPEN_STORAGE); +    return;    }  } @@ -105,8 +106,8 @@ void DOMStorageMessageFilter::OnLoadStorageArea(int connection_id,                                                  DOMStorageValuesMap* map) {    DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));    if (!host_->ExtractAreaValues(connection_id, map)) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_DSMF_2")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::DSMF_LOAD_STORAGE); +    return;    }    Send(new DOMStorageMsg_AsyncOperationComplete(true));  } diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc index ca67e18..9c10e43 100644 --- a/content/browser/fileapi/fileapi_message_filter.cc +++ b/content/browser/fileapi/fileapi_message_filter.cc @@ -15,6 +15,7 @@  #include "base/strings/string_util.h"  #include "base/threading/thread.h"  #include "base/time/time.h" +#include "content/browser/bad_message.h"  #include "content/browser/child_process_security_policy_impl.h"  #include "content/browser/fileapi/blob_storage_host.h"  #include "content/browser/fileapi/browser_file_system_helper.h" @@ -198,11 +199,6 @@ bool FileAPIMessageFilter::OnMessageReceived(const IPC::Message& message) {  FileAPIMessageFilter::~FileAPIMessageFilter() {} -void FileAPIMessageFilter::BadMessageReceived() { -  RecordAction(base::UserMetricsAction("BadMessageTerminate_FAMF")); -  BrowserMessageFilter::BadMessageReceived(); -} -  void FileAPIMessageFilter::OnOpenFileSystem(int request_id,                                              const GURL& origin_url,                                              storage::FileSystemType type) { @@ -537,7 +533,8 @@ void FileAPIMessageFilter::OnAppendBlobDataItemToBlob(      return;    }    if (item.length() == 0) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::FAMF_APPEND_ITEM_TO_BLOB);      return;    }    ignore_result(blob_storage_host_->AppendBlobDataItem(uuid, item)); @@ -549,7 +546,8 @@ void FileAPIMessageFilter::OnAppendSharedMemoryToBlob(      size_t buffer_size) {    DCHECK(base::SharedMemory::IsHandleValid(handle));    if (!buffer_size) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::FAMF_APPEND_SHARED_MEMORY_TO_BLOB);      return;    }  #if defined(OS_WIN) @@ -603,7 +601,8 @@ void FileAPIMessageFilter::OnStartBuildingStream(    if (!StartsWithASCII(            url.path(), "blobinternal%3A///", true /* case_sensitive */)) {      NOTREACHED() << "Malformed Stream URL: " << url.spec(); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::FAMF_MALFORMED_STREAM_URL);      return;    }    // Use an empty security origin for now. Stream accepts a security origin @@ -627,7 +626,8 @@ void FileAPIMessageFilter::OnAppendBlobDataItemToStream(    // Data for stream is delivered as TYPE_BYTES item.    if (item.type() != storage::DataElement::TYPE_BYTES) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::FAMF_APPEND_ITEM_TO_STREAM);      return;    }    stream->AddData(item.bytes(), item.length()); @@ -637,7 +637,8 @@ void FileAPIMessageFilter::OnAppendSharedMemoryToStream(      const GURL& url, base::SharedMemoryHandle handle, size_t buffer_size) {    DCHECK(base::SharedMemory::IsHandleValid(handle));    if (!buffer_size) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::FAMF_APPEND_SHARED_MEMORY_TO_STREAM);      return;    }  #if defined(OS_WIN) diff --git a/content/browser/fileapi/fileapi_message_filter.h b/content/browser/fileapi/fileapi_message_filter.h index 805778b..3ad767e 100644 --- a/content/browser/fileapi/fileapi_message_filter.h +++ b/content/browser/fileapi/fileapi_message_filter.h @@ -82,8 +82,6 @@ class CONTENT_EXPORT FileAPIMessageFilter : public BrowserMessageFilter {   protected:    ~FileAPIMessageFilter() override; -  void BadMessageReceived() override; -   private:    typedef storage::FileSystemOperationRunner::OperationID OperationID; diff --git a/content/browser/indexed_db/indexed_db_dispatcher_host.cc b/content/browser/indexed_db/indexed_db_dispatcher_host.cc index 0ac2a3a..996e6a5 100644 --- a/content/browser/indexed_db/indexed_db_dispatcher_host.cc +++ b/content/browser/indexed_db/indexed_db_dispatcher_host.cc @@ -12,6 +12,7 @@  #include "base/process/process.h"  #include "base/stl_util.h"  #include "base/strings/utf_string_conversions.h" +#include "content/browser/bad_message.h"  #include "content/browser/child_process_security_policy_impl.h"  #include "content/browser/indexed_db/indexed_db_callbacks.h"  #include "content/browser/indexed_db/indexed_db_connection.h" @@ -414,8 +415,7 @@ ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(    if (!return_object) {      NOTREACHED() << "Uh oh, couldn't find object with id "                   << ipc_return_object_id; -    RecordAction(base::UserMetricsAction("BadMessageTerminate_IDBMF")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::IDBDH_GET_OR_TERMINATE);    }    return return_object;  } @@ -429,8 +429,7 @@ ObjectType* IndexedDBDispatcherHost::GetOrTerminateProcess(    if (!return_object) {      NOTREACHED() << "Uh oh, couldn't find object with id "                   << ipc_return_object_id; -    RecordAction(base::UserMetricsAction("BadMessageTerminate_IDBMF")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::IDBDH_GET_OR_TERMINATE);    }    return return_object;  } @@ -710,7 +709,8 @@ void IndexedDBDispatcherHost::DatabaseDispatcherHost::OnPut(        if (!info.file_path.empty()) {          path = base::FilePath::FromUTF16Unsafe(info.file_path);          if (!policy->CanReadFile(parent_->ipc_process_id_, path)) { -          parent_->BadMessageReceived(); +          bad_message::ReceivedBadMessage(parent_, +                                          bad_message::IDBDH_CAN_READ_FILE);            return;          }        } diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc index ade6e5d..c49cb3c 100644 --- a/content/browser/loader/resource_dispatcher_host_impl.cc +++ b/content/browser/loader/resource_dispatcher_host_impl.cc @@ -27,6 +27,7 @@  #include "base/time/time.h"  #include "content/browser/appcache/appcache_interceptor.h"  #include "content/browser/appcache/chrome_appcache_service.h" +#include "content/browser/bad_message.h"  #include "content/browser/cert_store_impl.h"  #include "content/browser/child_process_security_policy_impl.h"  #include "content/browser/download/download_resource_handler.h" @@ -1133,8 +1134,7 @@ void ResourceDispatcherHostImpl::BeginRequest(    // Reject invalid priority.    if (request_data.priority < net::MINIMUM_PRIORITY ||        request_data.priority > net::MAXIMUM_PRIORITY) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_RDH")); -    filter_->BadMessageReceived(); +    bad_message::ReceivedBadMessage(filter_, bad_message::RDH_INVALID_PRIORITY);      return;    } @@ -1159,8 +1159,8 @@ void ResourceDispatcherHostImpl::BeginRequest(        deferred_loader->CompleteTransfer();      } else { -      RecordAction(base::UserMetricsAction("BadMessageTerminate_RDH")); -      filter_->BadMessageReceived(); +      bad_message::ReceivedBadMessage( +          filter_, bad_message::RDH_REQUEST_NOT_TRANSFERRING);      }      return;    } @@ -1354,8 +1354,7 @@ scoped_ptr<ResourceHandler> ResourceDispatcherHostImpl::CreateResourceHandler(    if (sync_result) {      // download_to_file is not supported for synchronous requests.      if (request_data.download_to_file) { -      RecordAction(base::UserMetricsAction("BadMessageTerminate_RDH")); -      filter_->BadMessageReceived(); +      bad_message::ReceivedBadMessage(filter_, bad_message::RDH_BAD_DOWNLOAD);        return scoped_ptr<ResourceHandler>();      } diff --git a/content/browser/media/midi_host.cc b/content/browser/media/midi_host.cc index 721095e..d610025 100644 --- a/content/browser/media/midi_host.cc +++ b/content/browser/media/midi_host.cc @@ -8,6 +8,7 @@  #include "base/bind_helpers.h"  #include "base/process/process.h"  #include "base/trace_event/trace_event.h" +#include "content/browser/bad_message.h"  #include "content/browser/browser_main_loop.h"  #include "content/browser/child_process_security_policy_impl.h"  #include "content/browser/media/media_internals.h" @@ -92,8 +93,7 @@ void MidiHost::OnSendData(uint32 port,    {      base::AutoLock auto_lock(output_port_count_lock_);      if (output_port_count_ <= port) { -      RecordAction(base::UserMetricsAction("BadMessageTerminate_MIDIPort")); -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::MH_INVALID_MIDI_PORT);        return;      }    } @@ -106,8 +106,7 @@ void MidiHost::OnSendData(uint32 port,    // happens here in the browser process.    if (!has_sys_ex_permission_ &&        std::find(data.begin(), data.end(), kSysExByte) != data.end()) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_MIDI")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::MH_SYS_EX_PERMISSION);      return;    } diff --git a/content/browser/media/midi_host_unittest.cc b/content/browser/media/midi_host_unittest.cc index 29f0796..bfe0c2f 100644 --- a/content/browser/media/midi_host_unittest.cc +++ b/content/browser/media/midi_host_unittest.cc @@ -91,10 +91,10 @@ class MidiHostForTesting : public MidiHost {    ~MidiHostForTesting() override {}    // BrowserMessageFilter implementation. -  // Override BadMessageReceived() so to do nothing since the original +  // Override ShutdownForBadMessage() to do nothing since the original    // implementation to kill a malicious renderer process causes a check failure    // in unit tests. -  void BadMessageReceived() override {} +  void ShutdownForBadMessage() override {}  };  class MidiHostTest : public testing::Test { diff --git a/content/browser/notifications/notification_message_filter.cc b/content/browser/notifications/notification_message_filter.cc index 9b9d381..8f22f42 100644 --- a/content/browser/notifications/notification_message_filter.cc +++ b/content/browser/notifications/notification_message_filter.cc @@ -5,6 +5,7 @@  #include "content/browser/notifications/notification_message_filter.h"  #include "base/callback.h" +#include "content/browser/bad_message.h"  #include "content/browser/notifications/page_notification_delegate.h"  #include "content/browser/notifications/platform_notification_context_impl.h"  #include "content/common/platform_notification_messages.h" @@ -138,7 +139,7 @@ void NotificationMessageFilter::OnShowPersistentNotification(    DCHECK_CURRENTLY_ON(BrowserThread::IO);    if (GetPermissionForOriginOnIO(origin) !=            blink::WebNotificationPermissionAllowed) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_SHOW);      return;    } @@ -257,7 +258,7 @@ void NotificationMessageFilter::OnClosePersistentNotification(    DCHECK_CURRENTLY_ON(BrowserThread::IO);    if (GetPermissionForOriginOnIO(origin) !=            blink::WebNotificationPermissionAllowed) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_CLOSE);      return;    } @@ -318,7 +319,7 @@ bool NotificationMessageFilter::VerifyNotificationPermissionGranted(    if (permission == blink::WebNotificationPermissionAllowed)      return true; -  BadMessageReceived(); +  bad_message::ReceivedBadMessage(this, bad_message::NMF_NO_PERMISSION_VERIFY);    return false;  } diff --git a/content/browser/renderer_host/database_message_filter.cc b/content/browser/renderer_host/database_message_filter.cc index 4b37773..ce06242 100644 --- a/content/browser/renderer_host/database_message_filter.cc +++ b/content/browser/renderer_host/database_message_filter.cc @@ -10,6 +10,7 @@  #include "base/strings/string_util.h"  #include "base/strings/utf_string_conversions.h"  #include "base/threading/thread.h" +#include "content/browser/bad_message.h"  #include "content/common/database_messages.h"  #include "content/public/browser/user_metrics.h"  #include "content/public/common/result_codes.h" @@ -295,8 +296,8 @@ void DatabaseMessageFilter::OnDatabaseOpened(    DCHECK_CURRENTLY_ON(BrowserThread::FILE);    if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::DBMF_INVALID_ORIGIN_ON_OPEN);      return;    } @@ -314,8 +315,8 @@ void DatabaseMessageFilter::OnDatabaseModified(    DCHECK_CURRENTLY_ON(BrowserThread::FILE);    if (!database_connections_.IsDatabaseOpened(            origin_identifier, database_name)) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::DBMF_DB_NOT_OPEN_ON_MODIFY);      return;    } @@ -328,8 +329,8 @@ void DatabaseMessageFilter::OnDatabaseClosed(    DCHECK_CURRENTLY_ON(BrowserThread::FILE);    if (!database_connections_.IsDatabaseOpened(            origin_identifier, database_name)) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::DBMF_DB_NOT_OPEN_ON_CLOSE);      return;    } @@ -343,8 +344,8 @@ void DatabaseMessageFilter::OnHandleSqliteError(      int error) {    DCHECK_CURRENTLY_ON(BrowserThread::FILE);    if (!DatabaseUtil::IsValidOriginIdentifier(origin_identifier)) { -    RecordAction(base::UserMetricsAction("BadMessageTerminate_DBMF")); -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::DBMF_INVALID_ORIGIN_ON_SQLITE_ERROR);      return;    } diff --git a/content/browser/service_worker/service_worker_dispatcher_host.cc b/content/browser/service_worker/service_worker_dispatcher_host.cc index d7e33c1..16fb50b 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host.cc @@ -8,6 +8,7 @@  #include "base/profiler/scoped_tracker.h"  #include "base/strings/utf_string_conversions.h"  #include "base/trace_event/trace_event.h" +#include "content/browser/bad_message.h"  #include "content/browser/message_port_message_filter.h"  #include "content/browser/message_port_service.h"  #include "content/browser/service_worker/embedded_worker_registry.h" @@ -205,7 +206,7 @@ bool ServiceWorkerDispatcherHost::OnMessageReceived(      handled = GetContext()->embedded_worker_registry()->OnMessageReceived(          message, render_process_id_);      if (!handled) -      BadMessageReceived(); +      bad_message::ReceivedBadMessage(this, bad_message::SWDH_NOT_HANDLED);    }    return handled; @@ -286,14 +287,14 @@ void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(      return;    }    if (!pattern.is_valid() || !script_url.is_valid()) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_REGISTER_BAD_URL);      return;    }    ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(        render_process_id_, provider_id);    if (!provider_host) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_REGISTER_NO_HOST);      return;    }    if (!provider_host->IsContextAlive()) { @@ -317,7 +318,7 @@ void ServiceWorkerDispatcherHost::OnRegisterServiceWorker(    if (!CanRegisterServiceWorker(        provider_host->document_url(), pattern, script_url)) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_REGISTER_CANNOT);      return;    } @@ -373,14 +374,14 @@ void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(      return;    }    if (!pattern.is_valid()) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_UNREGISTER_BAD_URL);      return;    }    ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(        render_process_id_, provider_id);    if (!provider_host) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_UNREGISTER_NO_HOST);      return;    }    if (!provider_host->IsContextAlive()) { @@ -403,7 +404,7 @@ void ServiceWorkerDispatcherHost::OnUnregisterServiceWorker(    }    if (!CanUnregisterServiceWorker(provider_host->document_url(), pattern)) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_UNREGISTER_CANNOT);      return;    } @@ -446,14 +447,16 @@ void ServiceWorkerDispatcherHost::OnGetRegistration(      return;    }    if (!document_url.is_valid()) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::SWDH_GET_REGISTRATION_BAD_URL);      return;    }    ServiceWorkerProviderHost* provider_host = GetContext()->GetProviderHost(        render_process_id_, provider_id);    if (!provider_host) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::SWDH_GET_REGISTRATION_NO_HOST);      return;    }    if (!provider_host->IsContextAlive()) { @@ -474,7 +477,8 @@ void ServiceWorkerDispatcherHost::OnGetRegistration(    }    if (!CanGetRegistration(provider_host->document_url(), document_url)) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::SWDH_GET_REGISTRATION_CANNOT);      return;    } @@ -520,7 +524,8 @@ void ServiceWorkerDispatcherHost::OnGetRegistrationForReady(    ServiceWorkerProviderHost* provider_host =        GetContext()->GetProviderHost(render_process_id_, provider_id);    if (!provider_host) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_GET_REGISTRATION_FOR_READY_NO_HOST);      return;    }    if (!provider_host->IsContextAlive()) @@ -534,7 +539,8 @@ void ServiceWorkerDispatcherHost::OnGetRegistrationForReady(    if (!provider_host->GetRegistrationForReady(base::Bind(            &ServiceWorkerDispatcherHost::GetRegistrationForReadyComplete,            this, thread_id, request_id, provider_host->AsWeakPtr()))) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_GET_REGISTRATION_FOR_READY_ALREADY_IN_PROGRESS);    }  } @@ -549,7 +555,7 @@ void ServiceWorkerDispatcherHost::OnPostMessageToWorker(    ServiceWorkerHandle* handle = handles_.Lookup(handle_id);    if (!handle) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_POST_MESSAGE);      return;    } @@ -571,7 +577,8 @@ void ServiceWorkerDispatcherHost::OnProviderCreated(    if (!GetContext())      return;    if (GetContext()->GetProviderHost(render_process_id_, provider_id)) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::SWDH_PROVIDER_CREATED_NO_HOST);      return;    }    scoped_ptr<ServiceWorkerProviderHost> provider_host( @@ -590,7 +597,8 @@ void ServiceWorkerDispatcherHost::OnProviderDestroyed(int provider_id) {    if (!GetContext())      return;    if (!GetContext()->GetProviderHost(render_process_id_, provider_id)) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_PROVIDER_DESTROYED_NO_HOST);      return;    }    GetContext()->RemoveProviderHost(render_process_id_, provider_id); @@ -605,13 +613,14 @@ void ServiceWorkerDispatcherHost::OnSetHostedVersionId(    ServiceWorkerProviderHost* provider_host =        GetContext()->GetProviderHost(render_process_id_, provider_id);    if (!provider_host) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_SET_HOSTED_VERSION_NO_HOST);      return;    }    if (!provider_host->IsContextAlive())      return;    if (!provider_host->SetHostedVersionId(version_id)) -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, bad_message::SWDH_SET_HOSTED_VERSION);    ServiceWorkerVersion* version = GetContext()->GetLiveVersion(version_id);    if (!version) @@ -736,7 +745,8 @@ void ServiceWorkerDispatcherHost::OnWorkerScriptLoaded(    ServiceWorkerProviderHost* provider_host =        GetContext()->GetProviderHost(render_process_id_, provider_id);    if (!provider_host) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_WORKER_SCRIPT_LOAD_NO_HOST);      return;    } @@ -851,7 +861,8 @@ void ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount(                 "ServiceWorkerDispatcherHost::OnIncrementServiceWorkerRefCount");    ServiceWorkerHandle* handle = handles_.Lookup(handle_id);    if (!handle) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_INCREMENT_WORKER_BAD_HANDLE);      return;    }    handle->IncrementRefCount(); @@ -863,7 +874,8 @@ void ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount(                 "ServiceWorkerDispatcherHost::OnDecrementServiceWorkerRefCount");    ServiceWorkerHandle* handle = handles_.Lookup(handle_id);    if (!handle) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_DECREMENT_WORKER_BAD_HANDLE);      return;    }    handle->DecrementRefCount(); @@ -878,7 +890,8 @@ void ServiceWorkerDispatcherHost::OnIncrementRegistrationRefCount(    ServiceWorkerRegistrationHandle* handle =        registration_handles_.Lookup(registration_handle_id);    if (!handle) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_INCREMENT_REGISTRATION_BAD_HANDLE);      return;    }    handle->IncrementRefCount(); @@ -891,7 +904,8 @@ void ServiceWorkerDispatcherHost::OnDecrementRegistrationRefCount(    ServiceWorkerRegistrationHandle* handle =        registration_handles_.Lookup(registration_handle_id);    if (!handle) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage( +        this, bad_message::SWDH_DECREMENT_REGISTRATION_BAD_HANDLE);      return;    }    handle->DecrementRefCount(); @@ -1032,7 +1046,8 @@ ServiceWorkerContextCore* ServiceWorkerDispatcherHost::GetContext() {  void ServiceWorkerDispatcherHost::OnTerminateWorker(int handle_id) {    ServiceWorkerHandle* handle = handles_.Lookup(handle_id);    if (!handle) { -    BadMessageReceived(); +    bad_message::ReceivedBadMessage(this, +                                    bad_message::SWDH_TERMINATE_BAD_HANDLE);      return;    }    handle->version()->StopWorker( diff --git a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc index 8e925cd..1fdb416e 100644 --- a/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc +++ b/content/browser/service_worker/service_worker_dispatcher_host_unittest.cc @@ -54,7 +54,7 @@ class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {    IPC::TestSink* ipc_sink() { return helper_->ipc_sink(); } -  void BadMessageReceived() override { ++bad_messages_received_count_; } +  void ShutdownForBadMessage() override { ++bad_messages_received_count_; }    int bad_messages_received_count_; diff --git a/content/browser/service_worker/service_worker_handle_unittest.cc b/content/browser/service_worker/service_worker_handle_unittest.cc index 9daf395..1575628 100644 --- a/content/browser/service_worker/service_worker_handle_unittest.cc +++ b/content/browser/service_worker/service_worker_handle_unittest.cc @@ -56,7 +56,7 @@ class TestingServiceWorkerDispatcherHost : public ServiceWorkerDispatcherHost {    bool Send(IPC::Message* message) override { return helper_->Send(message); } -  void BadMessageReceived() override { ++bad_message_received_count_; } +  void ShutdownForBadMessage() override { ++bad_message_received_count_; }    int bad_message_received_count_; diff --git a/content/public/browser/browser_message_filter.cc b/content/public/browser/browser_message_filter.cc index cb75ff1..83068f1 100644 --- a/content/public/browser/browser_message_filter.cc +++ b/content/public/browser/browser_message_filter.cc @@ -176,13 +176,15 @@ bool BrowserMessageFilter::CheckCanDispatchOnUI(const IPC::Message& message,    return true;  } -void BrowserMessageFilter::BadMessageReceived() { +void BrowserMessageFilter::ShutdownForBadMessage() {    base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();    if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC))      return;    BrowserChildProcessHostImpl::HistogramBadMessageTerminated(        PROCESS_TYPE_RENDERER); + +  // TODO(nick): Shouldn't this call StopChildProcess on Android?    peer_process_.Terminate(content::RESULT_CODE_KILLED_BAD_MESSAGE, false);  } diff --git a/content/public/browser/browser_message_filter.h b/content/public/browser/browser_message_filter.h index 1966e58..183ccba 100644 --- a/content/public/browser/browser_message_filter.h +++ b/content/public/browser/browser_message_filter.h @@ -92,9 +92,10 @@ class CONTENT_EXPORT BrowserMessageFilter    static bool CheckCanDispatchOnUI(const IPC::Message& message,                                     IPC::Sender* sender); -  // Call this if a message couldn't be deserialized.  This kills the renderer. -  // Can be called on any thread. -  virtual void BadMessageReceived(); +  // Called by bad_message.h helpers if a message couldn't be deserialized. This +  // kills the renderer.  Can be called on any thread.  This doesn't log the +  // error details to UMA, so use the bad_message.h for your module instead. +  virtual void ShutdownForBadMessage();    const std::vector<uint32>& message_classes_to_filter() const {      return message_classes_to_filter_; diff --git a/extensions/browser/bad_message.h b/extensions/browser/bad_message.h index ab26aba..25a0789 100644 --- a/extensions/browser/bad_message.h +++ b/extensions/browser/bad_message.h @@ -37,7 +37,7 @@ enum BadMessageReason {  void ReceivedBadMessage(content::RenderProcessHost* host,                          BadMessageReason reason); -}  // bad_message +}  // namespace bad_message  }  // namespace extensions  #endif  // EXTENSIONS_BROWSER_BAD_MESSAGE_H_ diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 346cb32..3b79a51 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -40800,6 +40800,17 @@ Therefore, the affected-histogram name has to have at least one dot in it.    </summary>  </histogram> +<histogram name="Stability.BadMessageTerminated.Chrome" +    enum="BadMessageReasonChrome"> +  <owner>nick@chromium.org</owner> +  <owner>jamescook@chromium.org</owner> +  <summary> +    Count of processes killed by chrome/browser because they sent an IPC that +    couldn't be properly handled. Categories are the reasons (code locations) +    for the kills. +  </summary> +</histogram> +  <histogram name="Stability.BadMessageTerminated.Content"      enum="BadMessageReasonContent">    <owner>jam@chromium.org</owner> @@ -40821,6 +40832,16 @@ Therefore, the affected-histogram name has to have at least one dot in it.    </summary>  </histogram> +<histogram name="Stability.BadMessageTerminated.NaCl" +    enum="BadMessageReasonNaCl"> +  <owner>nick@chromium.org</owner> +  <owner>jamescook@chromium.org</owner> +  <summary> +    Count of processes killed because they sent a NaCl IPC that couldn't be +    properly handled. Categories are the reasons (code locations) for the kills. +  </summary> +</histogram> +  <histogram name="Stability.BrowserExitCodes" enum="WindowsExitCode">    <owner>siggi@chromium.org</owner>    <owner>erikwright@chromium.org</owner> @@ -48798,6 +48819,10 @@ Therefore, the affected-histogram name has to have at least one dot in it.    <int value="2" label="Failure"/>  </enum> +<enum name="BadMessageReasonChrome" type="int"> +  <int value="0" label="WRLHH_LOGGING_STOPPED_BAD_STATE"/> +</enum> +  <enum name="BadMessageReasonContent" type="int">    <int value="0" label="NC_IN_PAGE_NAVIGATION"/>    <int value="1" label="RFH_CAN_COMMIT_URL_BLOCKED"/> @@ -48819,6 +48844,64 @@ Therefore, the affected-histogram name has to have at least one dot in it.    <int value="17" label="RFPH_DETACH"/>    <int value="18" label="DFH_BAD_EMBEDDER_MESSAGE"/>    <int value="19" label="NC_AUTO_SUBFRAME"/> +  <int value="20" label="CSDH_NOT_RECOGNIZED"/> +  <int value="21" label="DSMF_OPEN_STORAGE"/> +  <int value="22" label="DSMF_LOAD_STORAGE"/> +  <int value="23" label="DBMF_INVALID_ORIGIN_ON_OPEN"/> +  <int value="24" label="DBMF_DB_NOT_OPEN_ON_MODIFY"/> +  <int value="25" label="DBMF_DB_NOT_OPEN_ON_CLOSE"/> +  <int value="26" label="DBMF_INVALID_ORIGIN_ON_SQLITE_ERROR"/> +  <int value="27" label="RDH_INVALID_PRIORITY"/> +  <int value="28" label="RDH_REQUEST_NOT_TRANSFERRING"/> +  <int value="29" label="RDH_BAD_DOWNLOAD"/> +  <int value="30" label="NMF_NO_PERMISSION_SHOW"/> +  <int value="31" label="NMF_NO_PERMISSION_CLOSE"/> +  <int value="32" label="NMF_NO_PERMISSION_VERIFY"/> +  <int value="33" label="MH_INVALID_MIDI_PORT"/> +  <int value="34" label="MH_SYS_EX_PERMISSION"/> +  <int value="35" label="ACDH_REGISTER"/> +  <int value="36" label="ACDH_UNREGISTER"/> +  <int value="37" label="ACDH_SET_SPAWNING"/> +  <int value="38" label="ACDH_SELECT_CACHE"/> +  <int value="39" label="ACDH_SELECT_CACHE_FOR_WORKER"/> +  <int value="40" label="ACDH_SELECT_CACHE_FOR_SHARED_WORKER"/> +  <int value="41" label="ACDH_MARK_AS_FOREIGN_ENTRY"/> +  <int value="42" label="ACDH_PENDING_REPLY_IN_GET_STATUS"/> +  <int value="43" label="ACDH_GET_STATUS"/> +  <int value="44" label="ACDH_PENDING_REPLY_IN_START_UPDATE"/> +  <int value="45" label="ACDH_START_UPDATE"/> +  <int value="46" label="ACDH_PENDING_REPLY_IN_SWAP_CACHE"/> +  <int value="47" label="ACDH_SWAP_CACHE"/> +  <int value="48" label="SWDH_NOT_HANDLED"/> +  <int value="49" label="SWDH_REGISTER_BAD_URL"/> +  <int value="50" label="SWDH_REGISTER_NO_HOST"/> +  <int value="51" label="SWDH_REGISTER_CANNOT"/> +  <int value="52" label="SWDH_UNREGISTER_BAD_URL"/> +  <int value="53" label="SWDH_UNREGISTER_NO_HOST"/> +  <int value="54" label="SWDH_UNREGISTER_CANNOT"/> +  <int value="55" label="SWDH_GET_REGISTRATION_BAD_URL"/> +  <int value="56" label="SWDH_GET_REGISTRATION_NO_HOST"/> +  <int value="57" label="SWDH_GET_REGISTRATION_CANNOT"/> +  <int value="58" label="SWDH_GET_REGISTRATION_FOR_READY_NO_HOST"/> +  <int value="59" label="SWDH_GET_REGISTRATION_FOR_READY_ALREADY_IN_PROGRESS"/> +  <int value="60" label="SWDH_POST_MESSAGE"/> +  <int value="61" label="SWDH_PROVIDER_CREATED_NO_HOST"/> +  <int value="62" label="SWDH_PROVIDER_DESTROYED_NO_HOST"/> +  <int value="63" label="SWDH_SET_HOSTED_VERSION_NO_HOST"/> +  <int value="64" label="SWDH_SET_HOSTED_VERSION"/> +  <int value="65" label="SWDH_WORKER_SCRIPT_LOAD_NO_HOST"/> +  <int value="66" label="SWDH_INCREMENT_WORKER_BAD_HANDLE"/> +  <int value="67" label="SWDH_DECREMENT_WORKER_BAD_HANDLE"/> +  <int value="68" label="SWDH_INCREMENT_REGISTRATION_BAD_HANDLE"/> +  <int value="69" label="SWDH_DECREMENT_REGISTRATION_BAD_HANDLE"/> +  <int value="70" label="SWDH_TERMINATE_BAD_HANDLE"/> +  <int value="71" label="FAMF_APPEND_ITEM_TO_BLOB"/> +  <int value="72" label="FAMF_APPEND_SHARED_MEMORY_TO_BLOB"/> +  <int value="73" label="FAMF_MALFORMED_STREAM_URL"/> +  <int value="74" label="FAMF_APPEND_ITEM_TO_STREAM"/> +  <int value="75" label="FAMF_APPEND_SHARED_MEMORY_TO_STREAM"/> +  <int value="76" label="IDBDH_CAN_READ_FILE"/> +  <int value="77" label="IDBDH_GET_OR_TERMINATE"/>  </enum>  <enum name="BadMessageReasonExtensions" type="int"> @@ -48828,6 +48911,12 @@ Therefore, the affected-histogram name has to have at least one dot in it.    <int value="3" label="EH_BAD_EVENT_ID"/>  </enum> +<enum name="BadMessageReasonNaCl" type="int"> +  <int value="0" label="NFH_OPEN_EXECUTABLE_BAD_ROUTING_ID"/> +  <int value="1" label="NHMF_LAUNCH_CONTINUATION_BAD_ROUTING_ID"/> +  <int value="2" label="NHMF_GET_NEXE_FD_BAD_URL"/> +</enum> +  <enum name="BadSyncDataReason" type="int">    <int value="0" label="Bad extension ID"/>    <int value="1" label="Bad version"/> | 
