| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "extensions/browser/extension_function.h" | 5 #include "extensions/browser/extension_function.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/macros.h" | 10 #include "base/macros.h" |
| 11 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 12 #include "base/memory/singleton.h" | 12 #include "base/memory/singleton.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
| 15 #include "base/synchronization/lock.h" | 15 #include "base/synchronization/lock.h" |
| 16 #include "content/public/browser/notification_source.h" | 16 #include "content/public/browser/notification_source.h" |
| 17 #include "content/public/browser/notification_types.h" | 17 #include "content/public/browser/notification_types.h" |
| 18 #include "content/public/browser/render_frame_host.h" | 18 #include "content/public/browser/render_frame_host.h" |
| 19 #include "content/public/browser/user_metrics.h" |
| 19 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
| 20 #include "content/public/browser/web_contents_observer.h" | 21 #include "content/public/browser/web_contents_observer.h" |
| 22 #include "extensions/browser/bad_message.h" |
| 21 #include "extensions/browser/extension_function_dispatcher.h" | 23 #include "extensions/browser/extension_function_dispatcher.h" |
| 22 #include "extensions/browser/extension_message_filter.h" | 24 #include "extensions/browser/extension_message_filter.h" |
| 23 #include "extensions/browser/extensions_browser_client.h" | 25 #include "extensions/browser/extensions_browser_client.h" |
| 26 #include "extensions/browser/io_thread_extension_message_filter.h" |
| 24 #include "extensions/common/error_utils.h" | 27 #include "extensions/common/error_utils.h" |
| 25 #include "extensions/common/extension_api.h" | 28 #include "extensions/common/extension_api.h" |
| 26 #include "extensions/common/extension_messages.h" | 29 #include "extensions/common/extension_messages.h" |
| 27 | 30 |
| 28 using content::BrowserThread; | 31 using content::BrowserThread; |
| 29 using content::RenderViewHost; | 32 using content::RenderViewHost; |
| 30 using content::WebContents; | 33 using content::WebContents; |
| 31 using extensions::ErrorUtils; | 34 using extensions::ErrorUtils; |
| 32 using extensions::ExtensionAPI; | 35 using extensions::ExtensionAPI; |
| 33 using extensions::Feature; | 36 using extensions::Feature; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 histogram_value); | 72 histogram_value); |
| 70 } else { | 73 } else { |
| 71 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.Functions.FailedTime.Over10ms", | 74 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.Functions.FailedTime.Over10ms", |
| 72 histogram_value); | 75 histogram_value); |
| 73 } | 76 } |
| 74 UMA_HISTOGRAM_TIMES("Extensions.Functions.FailedTotalExecutionTime", | 77 UMA_HISTOGRAM_TIMES("Extensions.Functions.FailedTotalExecutionTime", |
| 75 elapsed_time); | 78 elapsed_time); |
| 76 } | 79 } |
| 77 } | 80 } |
| 78 | 81 |
| 82 void LogBadMessage(extensions::functions::HistogramValue histogram_value) { |
| 83 content::RecordAction(base::UserMetricsAction("BadMessageTerminate_EFD")); |
| 84 // Track the specific function's |histogram_value|, as this may indicate a |
| 85 // bug in that API's implementation. |
| 86 UMA_HISTOGRAM_ENUMERATION("Extensions.BadMessageFunctionName", |
| 87 histogram_value, |
| 88 extensions::functions::ENUM_BOUNDARY); |
| 89 } |
| 90 |
| 91 template <class T> |
| 92 void ReceivedBadMessage(T* bad_message_sender, |
| 93 extensions::bad_message::BadMessageReason reason, |
| 94 extensions::functions::HistogramValue histogram_value) { |
| 95 LogBadMessage(histogram_value); |
| 96 // The renderer has done validation before sending extension api requests. |
| 97 // Therefore, we should never receive a request that is invalid in a way |
| 98 // that JSON validation in the renderer should have caught. It could be an |
| 99 // attacker trying to exploit the browser, so we crash the renderer instead. |
| 100 extensions::bad_message::ReceivedBadMessage(bad_message_sender, reason); |
| 101 } |
| 102 |
| 79 class ArgumentListResponseValue | 103 class ArgumentListResponseValue |
| 80 : public ExtensionFunction::ResponseValueObject { | 104 : public ExtensionFunction::ResponseValueObject { |
| 81 public: | 105 public: |
| 82 ArgumentListResponseValue(ExtensionFunction* function, | 106 ArgumentListResponseValue(ExtensionFunction* function, |
| 83 std::unique_ptr<base::ListValue> result) { | 107 std::unique_ptr<base::ListValue> result) { |
| 84 SetFunctionResults(function, std::move(result)); | 108 SetFunctionResults(function, std::move(result)); |
| 85 // It would be nice to DCHECK(error.empty()) but some legacy extension | 109 // It would be nice to DCHECK(error.empty()) but some legacy extension |
| 86 // function implementations... I'm looking at chrome.input.ime... do this | 110 // function implementations... I'm looking at chrome.input.ime... do this |
| 87 // for some reason. | 111 // for some reason. |
| 88 } | 112 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 115 } | 139 } |
| 116 | 140 |
| 117 ~ErrorResponseValue() override {} | 141 ~ErrorResponseValue() override {} |
| 118 | 142 |
| 119 bool Apply() override { return false; } | 143 bool Apply() override { return false; } |
| 120 }; | 144 }; |
| 121 | 145 |
| 122 class BadMessageResponseValue : public ExtensionFunction::ResponseValueObject { | 146 class BadMessageResponseValue : public ExtensionFunction::ResponseValueObject { |
| 123 public: | 147 public: |
| 124 explicit BadMessageResponseValue(ExtensionFunction* function) { | 148 explicit BadMessageResponseValue(ExtensionFunction* function) { |
| 125 function->set_bad_message(true); | 149 function->SetBadMessage(); |
| 126 NOTREACHED() << function->name() << ": bad message"; | 150 NOTREACHED() << function->name() << ": bad message"; |
| 127 } | 151 } |
| 128 | 152 |
| 129 ~BadMessageResponseValue() override {} | 153 ~BadMessageResponseValue() override {} |
| 130 | 154 |
| 131 bool Apply() override { return false; } | 155 bool Apply() override { return false; } |
| 132 }; | 156 }; |
| 133 | 157 |
| 134 class RespondNowAction : public ExtensionFunction::ResponseActionObject { | 158 class RespondNowAction : public ExtensionFunction::ResponseActionObject { |
| 135 public: | 159 public: |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 } | 336 } |
| 313 | 337 |
| 314 const base::ListValue* ExtensionFunction::GetResultList() const { | 338 const base::ListValue* ExtensionFunction::GetResultList() const { |
| 315 return results_.get(); | 339 return results_.get(); |
| 316 } | 340 } |
| 317 | 341 |
| 318 const std::string& ExtensionFunction::GetError() const { | 342 const std::string& ExtensionFunction::GetError() const { |
| 319 return error_; | 343 return error_; |
| 320 } | 344 } |
| 321 | 345 |
| 346 void ExtensionFunction::SetBadMessage() { |
| 347 bad_message_ = true; |
| 348 } |
| 349 |
| 322 bool ExtensionFunction::user_gesture() const { | 350 bool ExtensionFunction::user_gesture() const { |
| 323 return user_gesture_ || UserGestureForTests::GetInstance()->HaveGesture(); | 351 return user_gesture_ || UserGestureForTests::GetInstance()->HaveGesture(); |
| 324 } | 352 } |
| 325 | 353 |
| 326 ExtensionFunction::ResponseValue ExtensionFunction::NoArguments() { | 354 ExtensionFunction::ResponseValue ExtensionFunction::NoArguments() { |
| 327 return ResponseValue( | 355 return ResponseValue( |
| 328 new ArgumentListResponseValue(this, base::MakeUnique<base::ListValue>())); | 356 new ArgumentListResponseValue(this, base::MakeUnique<base::ListValue>())); |
| 329 } | 357 } |
| 330 | 358 |
| 331 ExtensionFunction::ResponseValue ExtensionFunction::OneArgument( | 359 ExtensionFunction::ResponseValue ExtensionFunction::OneArgument( |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 501 // here and use weakptrs for the tasks, then have it owned by something that | 529 // here and use weakptrs for the tasks, then have it owned by something that |
| 502 // will be destroyed naturally in the course of shut down. | 530 // will be destroyed naturally in the course of shut down. |
| 503 if (extensions::ExtensionsBrowserClient::Get()->IsShuttingDown()) { | 531 if (extensions::ExtensionsBrowserClient::Get()->IsShuttingDown()) { |
| 504 *error = "The browser is shutting down."; | 532 *error = "The browser is shutting down."; |
| 505 return false; | 533 return false; |
| 506 } | 534 } |
| 507 | 535 |
| 508 return true; | 536 return true; |
| 509 } | 537 } |
| 510 | 538 |
| 539 void UIThreadExtensionFunction::SetBadMessage() { |
| 540 ExtensionFunction::SetBadMessage(); |
| 541 |
| 542 if (render_frame_host()) { |
| 543 ReceivedBadMessage(render_frame_host()->GetProcess(), |
| 544 is_from_service_worker() |
| 545 ? extensions::bad_message::EFD_BAD_MESSAGE_WORKER |
| 546 : extensions::bad_message::EFD_BAD_MESSAGE, |
| 547 histogram_value()); |
| 548 } |
| 549 } |
| 550 |
| 511 bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message& message) { | 551 bool UIThreadExtensionFunction::OnMessageReceived(const IPC::Message& message) { |
| 512 return false; | 552 return false; |
| 513 } | 553 } |
| 514 | 554 |
| 515 void UIThreadExtensionFunction::Destruct() const { | 555 void UIThreadExtensionFunction::Destruct() const { |
| 516 BrowserThread::DeleteOnUIThread::Destruct(this); | 556 BrowserThread::DeleteOnUIThread::Destruct(this); |
| 517 } | 557 } |
| 518 | 558 |
| 519 void UIThreadExtensionFunction::SetRenderFrameHost( | 559 void UIThreadExtensionFunction::SetRenderFrameHost( |
| 520 content::RenderFrameHost* render_frame_host) { | 560 content::RenderFrameHost* render_frame_host) { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 570 } | 610 } |
| 571 | 611 |
| 572 IOThreadExtensionFunction::~IOThreadExtensionFunction() { | 612 IOThreadExtensionFunction::~IOThreadExtensionFunction() { |
| 573 } | 613 } |
| 574 | 614 |
| 575 IOThreadExtensionFunction* | 615 IOThreadExtensionFunction* |
| 576 IOThreadExtensionFunction::AsIOThreadExtensionFunction() { | 616 IOThreadExtensionFunction::AsIOThreadExtensionFunction() { |
| 577 return this; | 617 return this; |
| 578 } | 618 } |
| 579 | 619 |
| 620 void IOThreadExtensionFunction::SetBadMessage() { |
| 621 ExtensionFunction::SetBadMessage(); |
| 622 if (ipc_sender_) { |
| 623 ReceivedBadMessage( |
| 624 static_cast<content::BrowserMessageFilter*>(ipc_sender_.get()), |
| 625 extensions::bad_message::EFD_BAD_MESSAGE, histogram_value()); |
| 626 } |
| 627 } |
| 628 |
| 580 void IOThreadExtensionFunction::Destruct() const { | 629 void IOThreadExtensionFunction::Destruct() const { |
| 581 BrowserThread::DeleteOnIOThread::Destruct(this); | 630 BrowserThread::DeleteOnIOThread::Destruct(this); |
| 582 } | 631 } |
| 583 | 632 |
| 584 AsyncExtensionFunction::AsyncExtensionFunction() { | 633 AsyncExtensionFunction::AsyncExtensionFunction() { |
| 585 } | 634 } |
| 586 | 635 |
| 587 void AsyncExtensionFunction::SetError(const std::string& error) { | 636 void AsyncExtensionFunction::SetError(const std::string& error) { |
| 588 error_ = error; | 637 error_ = error; |
| 589 } | 638 } |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 void AsyncExtensionFunction::SendResponse(bool success) { | 678 void AsyncExtensionFunction::SendResponse(bool success) { |
| 630 ResponseValue response; | 679 ResponseValue response; |
| 631 if (success) { | 680 if (success) { |
| 632 response = ArgumentList(std::move(results_)); | 681 response = ArgumentList(std::move(results_)); |
| 633 } else { | 682 } else { |
| 634 response = results_ ? ErrorWithArguments(std::move(results_), error_) | 683 response = results_ ? ErrorWithArguments(std::move(results_), error_) |
| 635 : Error(error_); | 684 : Error(error_); |
| 636 } | 685 } |
| 637 Respond(std::move(response)); | 686 Respond(std::move(response)); |
| 638 } | 687 } |
| OLD | NEW |