summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwfh <wfh@chromium.org>2015-01-21 06:36:46 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-21 14:38:17 +0000
commit0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce (patch)
tree1f30ce9cd48cba479715c1cc6d6cbe8bb02d404b
parentd7ce058384dd92263b59836d11e6fde7950e3eb7 (diff)
downloadchromium_src-0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce.zip
chromium_src-0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce.tar.gz
chromium_src-0539f2f5214fc17fdd5d1964be0ceedf98fdb9ce.tar.bz2
Block NPAPI plugins by default
Add --enable-npapi flag in chrome://flags to support re-enable. BUG=295137 TEST=browser_tests, unit_tests, content_browsertests, blink layout tests Review URL: https://codereview.chromium.org/645203002 Cr-Commit-Position: refs/heads/master@{#312374}
-rw-r--r--chrome/app/generated_resources.grd8
-rw-r--r--chrome/browser/about_flags.cc9
-rw-r--r--chrome/browser/content_settings/content_settings_browsertest.cc68
-rw-r--r--chrome/browser/plugins/plugin_prefs_unittest.cc1
-rw-r--r--chrome/browser/prerender/prerender_browsertest.cc1
-rw-r--r--chrome/test/data/load_npapi_plugin.html31
-rw-r--r--content/browser/plugin_browsertest.cc1
-rw-r--r--content/browser/plugin_service_impl.cc31
-rw-r--r--content/browser/plugin_service_impl.h3
-rw-r--r--content/public/browser/plugin_service.h3
-rw-r--r--content/public/common/content_switches.cc3
-rw-r--r--content/public/common/content_switches.h2
-rw-r--r--content/shell/app/shell_main_delegate.cc3
-rw-r--r--content/test/fake_plugin_service.cc3
-rw-r--r--content/test/fake_plugin_service.h1
-rw-r--r--content/test/plugin/plugin_client.cc53
-rw-r--r--tools/metrics/histograms/histograms.xml17
17 files changed, 230 insertions, 8 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 3f0bfe3..5b776a1 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5794,6 +5794,14 @@ Keep your key file in a safe place. You will need it to create new versions of y
Enables the win32k renderer lockdown, which is only available on Windows 8 and above.
</message>
</if>
+ <if expr="is_win or is_macosx">
+ <message name="IDS_FLAGS_ENABLE_NPAPI_NAME" desc="Name of the 'Enable NPAPI' lab.">
+ Enable NPAPI
+ </message>
+ <message name="IDS_FLAGS_ENABLE_NPAPI_DESCRIPTION" desc="Description of the 'Enable NPAPI' lab.">
+ Enables the use of NPAPI plugins.
+ </message>
+ </if>
<message name="IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_NAME" desc="Name of the 'Enable experimental canvas features' lab.">
Enable experimental canvas features
</message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 09b672c..15baf08 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -500,6 +500,15 @@ const Experiment kExperiments[] = {
kOsAll,
SINGLE_VALUE_TYPE(switches::kDisableExperimentalWebGL)
},
+#if defined(OS_WIN) || defined(OS_MACOSX)
+ {
+ "enable-npapi",
+ IDS_FLAGS_ENABLE_NPAPI_NAME,
+ IDS_FLAGS_ENABLE_NPAPI_DESCRIPTION,
+ kOsWin | kOsMac,
+ SINGLE_VALUE_TYPE(switches::kEnableNpapi)
+ },
+#endif
{
"disable-webrtc",
IDS_FLAGS_DISABLE_WEBRTC_NAME,
diff --git a/chrome/browser/content_settings/content_settings_browsertest.cc b/chrome/browser/content_settings/content_settings_browsertest.cc
index f6f0606..1ed96bb 100644
--- a/chrome/browser/content_settings/content_settings_browsertest.cc
+++ b/chrome/browser/content_settings/content_settings_browsertest.cc
@@ -294,20 +294,84 @@ IN_PROC_BROWSER_TEST_F(ContentSettingsTest, RedirectCrossOrigin) {
// On Aura NPAPI only works on Windows.
#if !defined(USE_AURA) || defined(OS_WIN)
+class LoadPluginTest : public ContentSettingsTest {
+ protected:
+ void PerformTest(bool expect_loaded) {
+ GURL url = ui_test_utils::GetTestUrl(
+ base::FilePath(),
+ base::FilePath().AppendASCII("load_npapi_plugin.html"));
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ const char* expected_result = expect_loaded ? "Loaded" : "Not Loaded";
+ const char* unexpected_result = expect_loaded ? "Not Loaded" : "Loaded";
+
+ base::string16 expected_title(base::ASCIIToUTF16(expected_result));
+ base::string16 unexpected_title(base::ASCIIToUTF16(unexpected_result));
+
+ content::TitleWatcher title_watcher(
+ browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
+ title_watcher.AlsoWaitForTitle(unexpected_title);
+
+ EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
+ }
+
+ void SetUpCommandLineInternal(base::CommandLine* command_line,
+ bool expect_loaded) {
+#if defined(OS_MACOSX)
+ base::FilePath plugin_dir;
+ PathService::Get(base::DIR_MODULE, &plugin_dir);
+ plugin_dir = plugin_dir.AppendASCII("plugins");
+ // The plugins directory isn't read by default on the Mac, so it needs to be
+ // explicitly registered.
+ command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir);
+#endif
+ command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins);
+ if (expect_loaded)
+ command_line->AppendSwitch(switches::kEnableNpapi);
+ }
+};
+
+class DisabledPluginTest : public LoadPluginTest {
+ public:
+ DisabledPluginTest() {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ SetUpCommandLineInternal(command_line, false);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(DisabledPluginTest, Load) {
+ PerformTest(false);
+}
+
+class EnabledPluginTest : public LoadPluginTest {
+ public:
+ EnabledPluginTest() {}
+
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ SetUpCommandLineInternal(command_line, true);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(EnabledPluginTest, Load) {
+ PerformTest(true);
+}
+
class ClickToPlayPluginTest : public ContentSettingsTest {
public:
ClickToPlayPluginTest() {}
-#if defined(OS_MACOSX)
void SetUpCommandLine(base::CommandLine* command_line) override {
+#if defined(OS_MACOSX)
base::FilePath plugin_dir;
PathService::Get(base::DIR_MODULE, &plugin_dir);
plugin_dir = plugin_dir.AppendASCII("plugins");
// The plugins directory isn't read by default on the Mac, so it needs to be
// explicitly registered.
command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir);
- }
#endif
+ command_line->AppendSwitch(switches::kEnableNpapi);
+ }
};
IN_PROC_BROWSER_TEST_F(ClickToPlayPluginTest, Basic) {
diff --git a/chrome/browser/plugins/plugin_prefs_unittest.cc b/chrome/browser/plugins/plugin_prefs_unittest.cc
index 12c4277..70deb5d 100644
--- a/chrome/browser/plugins/plugin_prefs_unittest.cc
+++ b/chrome/browser/plugins/plugin_prefs_unittest.cc
@@ -208,6 +208,7 @@ TEST_F(PluginPrefsTest, UnifiedPepperFlashState) {
PluginService::GetInstance()->Init();
PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
+ PluginService::GetInstance()->EnableNpapiPluginsForTesting();
base::string16 component_updated_plugin_name(
ASCIIToUTF16("Component-updated Pepper Flash"));
diff --git a/chrome/browser/prerender/prerender_browsertest.cc b/chrome/browser/prerender/prerender_browsertest.cc
index 002d32f..aa7447e 100644
--- a/chrome/browser/prerender/prerender_browsertest.cc
+++ b/chrome/browser/prerender/prerender_browsertest.cc
@@ -1082,6 +1082,7 @@ class PrerenderBrowserTest : virtual public InProcessBrowserTest {
app_dir.Append(FILE_PATH_LITERAL("plugins")));
#endif
command_line->AppendSwitch(switches::kAlwaysAuthorizePlugins);
+ command_line->AppendSwitch(switches::kEnableNpapi);
}
void SetPreference(NetworkPredictionOptions value) {
diff --git a/chrome/test/data/load_npapi_plugin.html b/chrome/test/data/load_npapi_plugin.html
new file mode 100644
index 0000000..2b91f5f
--- /dev/null
+++ b/chrome/test/data/load_npapi_plugin.html
@@ -0,0 +1,31 @@
+<html>
+<head>
+<title>Initial Title</title>
+<script>
+function PluginCreated() {
+ document.title = "Loaded";
+}
+
+function injectPlugin() {
+ var child = document.createElement('div');
+ child.innerHTML = '<embed type="application/vnd.npapi-test" src="foo"' +
+ ' name="invoke_js_function_on_create" id="plugin"' +
+ ' mode="np_embed"></embed>';
+ document.getElementById('content').appendChild(child);
+ // Plugins are loaded synchronously during layout, so the plugin has either
+ // been loaded or blocked at this point.
+ var plugin = document.getElementById('plugin');
+ // Check for the "loadedProperty" to determine if plugin is loaded.
+ if (plugin.loadedProperty == true) {
+ document.title = "Loaded";
+ } else {
+ document.title = "Not Loaded";
+ }
+}
+</script>
+</head>
+<body onload='injectPlugin();'>
+<div id='content'></div>
+</embed>
+</body>
+</html>
diff --git a/content/browser/plugin_browsertest.cc b/content/browser/plugin_browsertest.cc
index e1e5c30..9f55c96 100644
--- a/content/browser/plugin_browsertest.cc
+++ b/content/browser/plugin_browsertest.cc
@@ -74,6 +74,7 @@ class PluginTest : public ContentBrowserTest {
// explicitly registered.
command_line->AppendSwitchPath(switches::kExtraPluginDir, plugin_dir);
#endif
+ command_line->AppendSwitch(switches::kEnableNpapi);
}
void SetUpOnMainThread() override {
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc
index 49b6638..42ac63b 100644
--- a/content/browser/plugin_service_impl.cc
+++ b/content/browser/plugin_service_impl.cc
@@ -59,6 +59,16 @@ enum FlashUsage {
FLASH_USAGE_ENUM_COUNT
};
+enum NPAPIPluginStatus {
+ // Platform does not support NPAPI.
+ NPAPI_STATUS_UNSUPPORTED,
+ // Platform supports NPAPI and NPAPI is disabled.
+ NPAPI_STATUS_DISABLED,
+ // Platform supports NPAPI and NPAPI is enabled.
+ NPAPI_STATUS_ENABLED,
+ NPAPI_STATUS_ENUM_COUNT
+};
+
bool LoadPluginListInProcess() {
#if defined(OS_WIN)
return true;
@@ -143,7 +153,7 @@ PluginServiceImpl* PluginServiceImpl::GetInstance() {
}
PluginServiceImpl::PluginServiceImpl()
- : filter_(NULL) {
+ : npapi_plugins_enabled_(false), filter_(NULL) {
// Collect the total number of browser processes (which create
// PluginServiceImpl objects, to be precise). The number is used to normalize
// the number of processes which start at least one NPAPI/PPAPI Flash process.
@@ -180,6 +190,15 @@ void PluginServiceImpl::Init() {
if (command_line->HasSwitch(switches::kDisablePluginsDiscovery))
PluginList::Singleton()->DisablePluginsDiscovery();
+#if defined(OS_WIN) || defined(OS_MACOSX)
+ npapi_plugins_enabled_ = command_line->HasSwitch(switches::kEnableNpapi);
+ NPAPIPluginStatus status =
+ npapi_plugins_enabled_ ? NPAPI_STATUS_ENABLED : NPAPI_STATUS_DISABLED;
+#else
+ NPAPIPluginStatus status = NPAPI_STATUS_UNSUPPORTED;
+#endif
+ UMA_HISTOGRAM_ENUMERATION("Plugin.NPAPIStatus", status,
+ NPAPI_STATUS_ENUM_COUNT);
}
void PluginServiceImpl::StartWatchingPlugins() {
@@ -778,17 +797,17 @@ void PluginServiceImpl::GetInternalPlugins(
}
bool PluginServiceImpl::NPAPIPluginsSupported() {
-#if defined(OS_WIN) || defined(OS_MACOSX)
- return true;
-#else
- return false;
-#endif
+ return npapi_plugins_enabled_;
}
void PluginServiceImpl::DisablePluginsDiscoveryForTesting() {
PluginList::Singleton()->DisablePluginsDiscovery();
}
+void PluginServiceImpl::EnableNpapiPluginsForTesting() {
+ npapi_plugins_enabled_ = true;
+}
+
#if defined(OS_MACOSX)
void PluginServiceImpl::AppActivated() {
BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h
index 8770974..6b25ed4 100644
--- a/content/browser/plugin_service_impl.h
+++ b/content/browser/plugin_service_impl.h
@@ -106,6 +106,7 @@ class CONTENT_EXPORT PluginServiceImpl
void UnregisterInternalPlugin(const base::FilePath& path) override;
void GetInternalPlugins(std::vector<WebPluginInfo>* plugins) override;
bool NPAPIPluginsSupported() override;
+ void EnableNpapiPluginsForTesting() override;
void DisablePluginsDiscoveryForTesting() override;
#if defined(OS_MACOSX)
void AppActivated() override;
@@ -226,6 +227,8 @@ class CONTENT_EXPORT PluginServiceImpl
base::win::RegKey hklm_key_;
#endif
+ bool npapi_plugins_enabled_;
+
#if defined(OS_POSIX) && !defined(OS_OPENBSD) && !defined(OS_ANDROID)
ScopedVector<base::FilePathWatcher> file_watchers_;
#endif
diff --git a/content/public/browser/plugin_service.h b/content/public/browser/plugin_service.h
index cebc890..9121e68 100644
--- a/content/public/browser/plugin_service.h
+++ b/content/public/browser/plugin_service.h
@@ -143,6 +143,9 @@ class PluginService {
// This can be called from any thread.
virtual bool NPAPIPluginsSupported() = 0;
+ // This is equivalent to specifying kEnableNpapi, but is useful for unittests.
+ virtual void EnableNpapiPluginsForTesting() = 0;
+
// This is equivalent to specifying kDisablePluginsDiscovery, but is useful
// for unittests.
virtual void DisablePluginsDiscoveryForTesting() = 0;
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc
index b9d93ed..830a7da 100644
--- a/content/public/common/content_switches.cc
+++ b/content/public/common/content_switches.cc
@@ -955,6 +955,9 @@ const char kEnableWin32kRendererLockDown[] =
const char kFontCacheSharedMemSuffix[] = "font-cache-shared-mem-suffix";
#endif
+// Enables the use of NPAPI plugins.
+const char kEnableNpapi[] = "enable-npapi";
+
#if defined(ENABLE_PLUGINS)
// Enables the plugin power saver feature.
const char kEnablePluginPowerSaver[] = "enable-plugin-power-saver";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h
index 2db8c17..6b72dbc 100644
--- a/content/public/common/content_switches.h
+++ b/content/public/common/content_switches.h
@@ -291,6 +291,8 @@ CONTENT_EXPORT extern const char kFontCacheSharedMemSuffix[];
CONTENT_EXPORT bool IsWin32kRendererLockdownEnabled();
#endif
+CONTENT_EXPORT extern const char kEnableNpapi[];
+
#if defined(ENABLE_PLUGINS)
CONTENT_EXPORT extern const char kEnablePluginPowerSaver[];
#endif
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index a4ec664..12e33cf 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -191,6 +191,9 @@ bool ShellMainDelegate::BasicStartupComplete(int* exit_code) {
command_line.AppendSwitchASCII(switches::kHostResolverRules,
"MAP *.test 127.0.0.1");
+ // TODO(wfh): crbug.com/295137 Remove this when NPAPI is gone.
+ command_line.AppendSwitch(switches::kEnableNpapi);
+
// Unless/until WebM files are added to the media layout tests, we need to
// avoid removing MP4/H264/AAC so that layout tests can run on Android.
#if !defined(OS_ANDROID)
diff --git a/content/test/fake_plugin_service.cc b/content/test/fake_plugin_service.cc
index 1d7767cb..75e35d4 100644
--- a/content/test/fake_plugin_service.cc
+++ b/content/test/fake_plugin_service.cc
@@ -101,6 +101,9 @@ bool FakePluginService::NPAPIPluginsSupported() {
return false;
}
+void FakePluginService::EnableNpapiPluginsForTesting() {
+}
+
void FakePluginService::DisablePluginsDiscoveryForTesting() {
}
diff --git a/content/test/fake_plugin_service.h b/content/test/fake_plugin_service.h
index b8d15d4..ed8450c 100644
--- a/content/test/fake_plugin_service.h
+++ b/content/test/fake_plugin_service.h
@@ -52,6 +52,7 @@ class FakePluginService : public PluginService {
void UnregisterInternalPlugin(const base::FilePath& path) override;
void GetInternalPlugins(std::vector<WebPluginInfo>* plugins) override;
bool NPAPIPluginsSupported() override;
+ void EnableNpapiPluginsForTesting() override;
void DisablePluginsDiscoveryForTesting() override;
#if defined(OS_MACOSX)
void AppActivated() override;
diff --git a/content/test/plugin/plugin_client.cc b/content/test/plugin/plugin_client.cc
index e5d0f8c..f2f4e68 100644
--- a/content/test/plugin/plugin_client.cc
+++ b/content/test/plugin/plugin_client.cc
@@ -11,6 +11,52 @@
namespace NPAPIClient {
+class NPWithProperty : public NPObject {
+ public:
+ NPWithProperty() : NPObject() {}
+
+ static NPObject* Allocate(NPP npp, NPClass* npclass) {
+ return new NPWithProperty();
+ }
+
+ static void Deallocate(NPObject* npobject) {
+ delete static_cast<NPWithProperty*>(npobject);
+ }
+
+ static bool HasProperty(NPObject* npobject, NPIdentifier name) {
+ return (name == PluginClient::HostFunctions()->
+ getstringidentifier("loadedProperty"));
+ }
+
+ static bool GetProperty(NPObject* npobject,
+ NPIdentifier name,
+ NPVariant* result) {
+ if (name == PluginClient::HostFunctions()->
+ getstringidentifier("loadedProperty")) {
+ BOOLEAN_TO_NPVARIANT(true, *result);
+ return true;
+ }
+ return false;
+ }
+};
+
+static NPClass* GetNPClass() {
+ static NPClass plugin_class = {
+ NP_CLASS_STRUCT_VERSION,
+ NPWithProperty::Allocate,
+ NPWithProperty::Deallocate,
+ NULL, // Invalidate
+ NULL, // HasMethod
+ NULL, // Invoke
+ NULL, // InvokeDefault
+ NPWithProperty::HasProperty,
+ NPWithProperty::GetProperty,
+ NULL, // SetProperty
+ NULL, // RemoveProperty
+ };
+ return &plugin_class;
+}
+
NPNetscapeFuncs* PluginClient::host_functions_;
NPError PluginClient::GetEntryPoints(NPPluginFuncs* pFuncs) {
@@ -230,6 +276,13 @@ NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) {
return NPERR_NO_ERROR;
}
+ if (variable == NPPVpluginScriptableNPObject) {
+ *(NPObject**)value =
+ NPAPIClient::PluginClient::HostFunctions()->createobject(
+ instance, NPAPIClient::GetNPClass());
+ return NPERR_NO_ERROR;
+ }
+
// XXXMB - do work here.
return NPERR_GENERIC_ERROR;
}
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index a33a454..125d719 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -25874,6 +25874,14 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<summary>Collects Flash usage data.</summary>
</histogram>
+<histogram name="Plugin.NPAPIStatus" enum="NPAPIPluginStatus">
+ <owner>wfh@chromium.org</owner>
+ <summary>
+ Records whether NPAPI plugins are supported by the platform, and if so,
+ whether they are enabled or disabled. Recorded once at browser startup.
+ </summary>
+</histogram>
+
<histogram name="Plugin.PowerSaver.PeripheralHeuristic"
enum="PluginPowerSaverPeripheralHeuristicDecision">
<owner>tommycli@chromium.org</owner>
@@ -50293,6 +50301,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="-1218608640" label="disable-offline-load-stale-cache"/>
<int value="-1212273428" label="enable-experimental-app-list"/>
<int value="-1201183153" label="enable-centered-app-list"/>
+ <int value="-1184904651" label="enable-npapi"/>
<int value="-1177802205" label="enable-hosted-app-quit-notification"/>
<int value="-1172204005" label="enable-offline-auto-reload-visible-only"/>
<int value="-1159563774" label="enable-accessibility-script-injection"/>
@@ -52415,6 +52424,14 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="7" label="Notification closed by system"/>
</enum>
+<enum name="NPAPIPluginStatus" type="int">
+ <int value="0" label="Unsupported">
+ NPAPI is not supported on this platform
+ </int>
+ <int value="1" label="Disabled">NPAPI is disabled</int>
+ <int value="2" label="Enabled">NPAPI is enabled</int>
+</enum>
+
<enum name="NtpFollowAction" type="int">
<int value="0" label="PAGE_TRANSITION_LINK"/>
<int value="1" label="PAGE_TRANSITION_TYPED"/>