Commit ed033322 authored by kalman's avatar kalman Committed by Commit bot

[Extensions] Record the extension function names which send a bad message.

BUG=462026
R=yoz@chromium.org

Review URL: https://codereview.chromium.org/957113002

Cr-Commit-Position: refs/heads/master@{#318830}
parent ef44b274
...@@ -404,7 +404,7 @@ void ExtensionFunction::SendResponseImpl(bool success) { ...@@ -404,7 +404,7 @@ void ExtensionFunction::SendResponseImpl(bool success) {
if (!results_) if (!results_)
results_.reset(new base::ListValue()); results_.reset(new base::ListValue());
response_callback_.Run(type, *results_, GetError()); response_callback_.Run(type, *results_, GetError(), histogram_value());
} }
void ExtensionFunction::OnRespondingLater(ResponseValue value) { void ExtensionFunction::OnRespondingLater(ResponseValue value) {
......
...@@ -100,9 +100,11 @@ class ExtensionFunction ...@@ -100,9 +100,11 @@ class ExtensionFunction
BAD_MESSAGE BAD_MESSAGE
}; };
typedef base::Callback<void(ResponseType type, using ResponseCallback = base::Callback<void(
ResponseType type,
const base::ListValue& results, const base::ListValue& results,
const std::string& error)> ResponseCallback; const std::string& error,
extensions::functions::HistogramValue histogram_value)>;
ExtensionFunction(); ExtensionFunction();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/lazy_instance.h" #include "base/lazy_instance.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/sparse_histogram.h" #include "base/metrics/sparse_histogram.h"
#include "base/process/process.h" #include "base/process/process.h"
#include "base/profiler/scoped_profile.h" #include "base/profiler/scoped_profile.h"
...@@ -81,9 +82,14 @@ struct Static { ...@@ -81,9 +82,14 @@ struct Static {
base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER; base::LazyInstance<Static> g_global_io_data = LAZY_INSTANCE_INITIALIZER;
// Kills the specified process because it sends us a malformed message. // Kills the specified process because it sends us a malformed message.
void KillBadMessageSender(base::ProcessHandle process) { // Track the specific function's |histogram_value|, as this may indicate a bug
// in that API's implementation on the renderer.
void KillBadMessageSender(base::ProcessHandle process,
functions::HistogramValue histogram_value) {
NOTREACHED(); NOTREACHED();
content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD")); content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD"));
UMA_HISTOGRAM_ENUMERATION("Extensions.BadMessageFunctionName",
histogram_value, functions::ENUM_BOUNDARY);
if (process) if (process)
base::KillProcess(process, content::RESULT_CODE_KILLED_BAD_MESSAGE, false); base::KillProcess(process, content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
} }
...@@ -94,7 +100,8 @@ void CommonResponseCallback(IPC::Sender* ipc_sender, ...@@ -94,7 +100,8 @@ void CommonResponseCallback(IPC::Sender* ipc_sender,
int request_id, int request_id,
ExtensionFunction::ResponseType type, ExtensionFunction::ResponseType type,
const base::ListValue& results, const base::ListValue& results,
const std::string& error) { const std::string& error,
functions::HistogramValue histogram_value) {
DCHECK(ipc_sender); DCHECK(ipc_sender);
if (type == ExtensionFunction::BAD_MESSAGE) { if (type == ExtensionFunction::BAD_MESSAGE) {
...@@ -108,9 +115,8 @@ void CommonResponseCallback(IPC::Sender* ipc_sender, ...@@ -108,9 +115,8 @@ void CommonResponseCallback(IPC::Sender* ipc_sender,
// In single process mode it is better if we don't suicide but just crash. // In single process mode it is better if we don't suicide but just crash.
CHECK(false); CHECK(false);
} else { } else {
KillBadMessageSender(peer_process); KillBadMessageSender(peer_process, histogram_value);
} }
return; return;
} }
...@@ -125,17 +131,13 @@ void IOThreadResponseCallback( ...@@ -125,17 +131,13 @@ void IOThreadResponseCallback(
int request_id, int request_id,
ExtensionFunction::ResponseType type, ExtensionFunction::ResponseType type,
const base::ListValue& results, const base::ListValue& results,
const std::string& error) { const std::string& error,
functions::HistogramValue histogram_value) {
if (!ipc_sender.get()) if (!ipc_sender.get())
return; return;
CommonResponseCallback(ipc_sender.get(), CommonResponseCallback(ipc_sender.get(), routing_id, ipc_sender->PeerHandle(),
routing_id, request_id, type, results, error, histogram_value);
ipc_sender->PeerHandle(),
request_id,
type,
results,
error);
} }
} // namespace } // namespace
...@@ -180,11 +182,11 @@ class ExtensionFunctionDispatcher::UIThreadResponseCallbackWrapper ...@@ -180,11 +182,11 @@ class ExtensionFunctionDispatcher::UIThreadResponseCallbackWrapper
void OnExtensionFunctionCompleted(int request_id, void OnExtensionFunctionCompleted(int request_id,
ExtensionFunction::ResponseType type, ExtensionFunction::ResponseType type,
const base::ListValue& results, const base::ListValue& results,
const std::string& error) { const std::string& error,
CommonResponseCallback( functions::HistogramValue histogram_value) {
render_view_host_, render_view_host_->GetRoutingID(), CommonResponseCallback(render_view_host_, render_view_host_->GetRoutingID(),
render_view_host_->GetProcess()->GetHandle(), request_id, type, render_view_host_->GetProcess()->GetHandle(),
results, error); request_id, type, results, error, histogram_value);
} }
base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_; base::WeakPtr<ExtensionFunctionDispatcher> dispatcher_;
...@@ -438,7 +440,7 @@ bool ExtensionFunctionDispatcher::CheckPermissions( ...@@ -438,7 +440,7 @@ bool ExtensionFunctionDispatcher::CheckPermissions(
const ExtensionFunction::ResponseCallback& callback) { const ExtensionFunction::ResponseCallback& callback) {
if (!function->HasPermission()) { if (!function->HasPermission()) {
LOG(ERROR) << "Permission denied for " << params.name; LOG(ERROR) << "Permission denied for " << params.name;
SendAccessDenied(callback); SendAccessDenied(callback, function->histogram_value());
return false; return false;
} }
return true; return true;
...@@ -457,7 +459,7 @@ ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( ...@@ -457,7 +459,7 @@ ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction(
ExtensionFunctionRegistry::GetInstance()->NewFunction(params.name); ExtensionFunctionRegistry::GetInstance()->NewFunction(params.name);
if (!function) { if (!function) {
LOG(ERROR) << "Unknown Extension API - " << params.name; LOG(ERROR) << "Unknown Extension API - " << params.name;
SendAccessDenied(callback); SendAccessDenied(callback, function->histogram_value());
return NULL; return NULL;
} }
...@@ -478,10 +480,11 @@ ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction( ...@@ -478,10 +480,11 @@ ExtensionFunction* ExtensionFunctionDispatcher::CreateExtensionFunction(
// static // static
void ExtensionFunctionDispatcher::SendAccessDenied( void ExtensionFunctionDispatcher::SendAccessDenied(
const ExtensionFunction::ResponseCallback& callback) { const ExtensionFunction::ResponseCallback& callback,
functions::HistogramValue histogram_value) {
base::ListValue empty_list; base::ListValue empty_list;
callback.Run(ExtensionFunction::FAILED, empty_list, callback.Run(ExtensionFunction::FAILED, empty_list,
"Access to extension API denied."); "Access to extension API denied.", histogram_value);
} }
} // namespace extensions } // namespace extensions
...@@ -146,7 +146,8 @@ class ExtensionFunctionDispatcher ...@@ -146,7 +146,8 @@ class ExtensionFunctionDispatcher
// Helper to run the response callback with an access denied error. Can be // Helper to run the response callback with an access denied error. Can be
// called on any thread. // called on any thread.
static void SendAccessDenied( static void SendAccessDenied(
const ExtensionFunction::ResponseCallback& callback); const ExtensionFunction::ResponseCallback& callback,
functions::HistogramValue histogram_value);
void DispatchWithCallbackInternal( void DispatchWithCallbackInternal(
const ExtensionHostMsg_Request_Params& params, const ExtensionHostMsg_Request_Params& params,
......
...@@ -8442,6 +8442,16 @@ Therefore, the affected-histogram name has to have at least one dot in it. ...@@ -8442,6 +8442,16 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary> </summary>
</histogram> </histogram>
<histogram name="Extensions.BadMessageFunctionName" enum="ExtensionFunctions">
<owner>kalman@chromium.org</owner>
<summary>
The number of times each Extension function call sends a bad message,
killing the renderer. This may indicate a bug in that API's implementation
on the renderer. Note a similar, aggregate metric is BadMessageTerminate_EFD
which counts the number of bad messages that are sent overall.
</summary>
</histogram>
<histogram name="Extensions.CheckForExternalUpdatesTime"> <histogram name="Extensions.CheckForExternalUpdatesTime">
<owner>rkaplow@chromium.org</owner> <owner>rkaplow@chromium.org</owner>
<summary> <summary>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment