diff options
-rw-r--r-- | chrome/browser/renderer_host/plugin_info_message_filter.cc | 3 | ||||
-rw-r--r-- | content/browser/plugin_process_host.cc | 5 | ||||
-rw-r--r-- | content/browser/plugin_process_host.h | 1 | ||||
-rw-r--r-- | content/browser/plugin_service_impl.cc | 35 | ||||
-rw-r--r-- | content/browser/plugin_service_impl.h | 10 | ||||
-rw-r--r-- | content/public/browser/plugin_service.h | 4 |
6 files changed, 57 insertions, 1 deletions
diff --git a/chrome/browser/renderer_host/plugin_info_message_filter.cc b/chrome/browser/renderer_host/plugin_info_message_filter.cc index 33a46c0..9017c6b2 100644 --- a/chrome/browser/renderer_host/plugin_info_message_filter.cc +++ b/chrome/browser/renderer_host/plugin_info_message_filter.cc @@ -192,7 +192,8 @@ void PluginInfoMessageFilter::Context::DecidePluginStatus( } // Check if the plug-in requires authorization. - if (group->RequiresAuthorization(*plugin) && + if ((group->RequiresAuthorization(*plugin) || + PluginService::GetInstance()->IsPluginUnstable(plugin->path)) && !always_authorize && plugin_setting != CONTENT_SETTING_BLOCK && uses_default_content_setting) { diff --git a/content/browser/plugin_process_host.cc b/content/browser/plugin_process_host.cc index 5bb447a..14ddbfe 100644 --- a/content/browser/plugin_process_host.cc +++ b/content/browser/plugin_process_host.cc @@ -30,6 +30,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/notification_types.h" +#include "content/public/browser/plugin_service.h" #include "content/public/common/content_switches.h" #include "content/public/common/process_type.h" #include "ipc/ipc_switches.h" @@ -348,6 +349,10 @@ bool PluginProcessHost::CanShutdown() { return sent_requests_.empty(); } +void PluginProcessHost::OnProcessCrashed(int exit_code) { + PluginServiceImpl::GetInstance()->RegisterPluginCrash(info_.path); +} + void PluginProcessHost::CancelRequests() { for (size_t i = 0; i < pending_requests_.size(); ++i) pending_requests_[i]->OnError(); diff --git a/content/browser/plugin_process_host.h b/content/browser/plugin_process_host.h index a6c2596..0c93a64 100644 --- a/content/browser/plugin_process_host.h +++ b/content/browser/plugin_process_host.h @@ -150,6 +150,7 @@ class CONTENT_EXPORT PluginProcessHost #endif virtual bool CanShutdown() OVERRIDE; + virtual void OnProcessCrashed(int exit_code) OVERRIDE; void CancelRequests(); diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index f11603d6..7b2f2c6 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc @@ -626,6 +626,41 @@ void PluginServiceImpl::ForcePluginShutdown(const FilePath& plugin_path) { plugin->ForceShutdown(); } +static const unsigned int kMaxCrashesPerInterval = 3; +static const unsigned int kCrashesInterval = 120; + +void PluginServiceImpl::RegisterPluginCrash(const FilePath& path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + std::map<FilePath, std::vector<base::Time> >::iterator i = + crash_times_.find(path); + if (i == crash_times_.end()) { + crash_times_[path] = std::vector<base::Time>(); + i = crash_times_.find(path); + } + if (i->second.size() == kMaxCrashesPerInterval) { + i->second.erase(i->second.begin()); + } + base::Time time = base::Time::Now(); + i->second.push_back(time); +} + +bool PluginServiceImpl::IsPluginUnstable(const FilePath& path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + std::map<FilePath, std::vector<base::Time> >::const_iterator i = + crash_times_.find(path); + if (i == crash_times_.end()) { + return false; + } + if (i->second.size() != kMaxCrashesPerInterval) { + return false; + } + base::TimeDelta delta = base::Time::Now() - i->second[0]; + if (delta.InSeconds() <= kCrashesInterval) { + return true; + } + return false; +} + void PluginServiceImpl::RefreshPlugins() { plugin_list_->RefreshPlugins(); } diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index 602ca64..4b6976d 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h @@ -9,13 +9,16 @@ #define CONTENT_BROWSER_PLUGIN_SERVICE_IMPL_H_ #pragma once +#include <map> #include <set> +#include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/memory/scoped_vector.h" #include "base/memory/singleton.h" #include "base/synchronization/waitable_event_watcher.h" +#include "base/time.h" #include "build/build_config.h" #include "content/browser/plugin_process_host.h" #include "content/browser/ppapi_plugin_process_host.h" @@ -94,6 +97,7 @@ class CONTENT_EXPORT PluginServiceImpl virtual void SetFilter(content::PluginServiceFilter* filter) OVERRIDE; virtual content::PluginServiceFilter* GetFilter() OVERRIDE; virtual void ForcePluginShutdown(const FilePath& plugin_path) OVERRIDE; + virtual bool IsPluginUnstable(const FilePath& plugin_path) OVERRIDE; virtual void RefreshPlugins() OVERRIDE; virtual void AddExtraPluginPath(const FilePath& path) OVERRIDE; virtual void AddExtraPluginDir(const FilePath& path) OVERRIDE; @@ -135,6 +139,9 @@ class CONTENT_EXPORT PluginServiceImpl // Cancels opening a channel to a NPAPI plugin. void CancelOpenChannelToNpapiPlugin(PluginProcessHost::Client* client); + // Used to monitor plug-in stability. + void RegisterPluginCrash(const FilePath& plugin_path); + private: friend struct DefaultSingletonTraits<PluginServiceImpl>; @@ -228,6 +235,9 @@ class CONTENT_EXPORT PluginServiceImpl scoped_refptr<PluginLoaderPosix> plugin_loader_; #endif + // Used to detect if a given plug-in is crashing over and over. + std::map<FilePath, std::vector<base::Time> > crash_times_; + DISALLOW_COPY_AND_ASSIGN(PluginServiceImpl); }; diff --git a/content/public/browser/plugin_service.h b/content/public/browser/plugin_service.h index 34806b3..5be3d08 100644 --- a/content/public/browser/plugin_service.h +++ b/content/public/browser/plugin_service.h @@ -113,6 +113,10 @@ class PluginService { // If the plugin with the given path is running, cleanly shuts it down. virtual void ForcePluginShutdown(const FilePath& plugin_path) = 0; + // Used to monitor plug-in stability. An unstable plug-in is one that has + // crashed more than a set number of times in a set time period. + virtual bool IsPluginUnstable(const FilePath& plugin_path) = 0; + // The following functions are wrappers around webkit::npapi::PluginList. // These must be used instead of those in order to ensure that we have a // single global list in the component build and so that we don't |