summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvictorhsieh@chromium.org <victorhsieh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-29 20:29:40 +0000
committervictorhsieh@chromium.org <victorhsieh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-29 20:29:40 +0000
commit93f7206a5283807e3f72917204c3f8152c633bba (patch)
treeb5bed48454ed2dfe077596ba1a24e2126f97563f
parent081b544067287a9fc1ed42c0acb693a9a8b914d3 (diff)
downloadchromium_src-93f7206a5283807e3f72917204c3f8152c633bba.zip
chromium_src-93f7206a5283807e3f72917204c3f8152c633bba.tar.gz
chromium_src-93f7206a5283807e3f72917204c3f8152c633bba.tar.bz2
Flag and whitelist to allow crxfs api in NaCl
This is pretty much the same as existing Pepper Socket API. Since the original code for socket is in chrome_content_browser_client.h for crossing chrome-content boundary, it's moved to the new file pepper_util.cc, so that PepperCrxFileSystemMessageFilter can access directory inside chrome space. BUG=240865 Review URL: https://chromiumcodereview.appspot.com/15521002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202951 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/chrome_content_browser_client.cc78
-rw-r--r--chrome/browser/chrome_content_browser_client.h3
-rw-r--r--chrome/browser/pepper_permission_util.cc103
-rw-r--r--chrome/browser/pepper_permission_util.h26
-rw-r--r--chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc24
-rw-r--r--chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc35
-rw-r--r--chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.h10
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc2
11 files changed, 206 insertions, 82 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 87f22e9..f84a527 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -13,9 +13,7 @@
#include "base/lazy_instance.h"
#include "base/path_service.h"
#include "base/prefs/pref_service.h"
-#include "base/sha1.h"
#include "base/string_number_conversions.h"
-#include "base/strings/string_tokenizer.h"
#include "base/utf_string_conversions.h"
#include "chrome/app/breakpad_mac.h"
#include "chrome/browser/app_mode/app_mode_utils.h"
@@ -51,6 +49,7 @@
#include "chrome/browser/net/chrome_net_log.h"
#include "chrome/browser/notifications/desktop_notification_service.h"
#include "chrome/browser/notifications/desktop_notification_service_factory.h"
+#include "chrome/browser/pepper_permission_util.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/plugins/plugin_info_message_filter.h"
#include "chrome/browser/prefs/scoped_user_pref_update.h"
@@ -203,6 +202,7 @@ namespace {
// thread.
base::LazyInstance<std::string> g_io_thread_application_locale;
+#if defined(ENABLE_PLUGINS)
const char* kPredefinedAllowedSocketOrigins[] = {
"okddffdblfhhnmhodogpojmfkjmhinfp", // Test SSH Client
"pnhechapfaindjhompbnflcldabbghjo", // HTerm App (SSH Client)
@@ -225,6 +225,7 @@ const char* kPredefinedAllowedSocketOrigins[] = {
"0B549507088E1564D672F7942EB87CA4DAD73972", // see crbug.com/238084
"864288364E239573E777D3E0E36864E590E95C74" // see crbug.com/238084
};
+#endif
// Returns a copy of the given url with its host set to given host and path set
// to given path. Other parts of the url will be the same.
@@ -464,23 +465,15 @@ void SetApplicationLocaleOnIOThread(const std::string& locale) {
g_io_thread_application_locale.Get() = locale;
}
-std::string HashHost(const std::string& host) {
- const std::string id_hash = base::SHA1HashString(host);
- DCHECK(id_hash.length() == base::kSHA1Length);
- return base::HexEncode(id_hash.c_str(), id_hash.length());
-}
-
-bool HostIsInSet(const std::string& host, const std::set<std::string>& set) {
- return set.count(host) > 0 || set.count(HashHost(host)) > 0;
-}
-
} // namespace
namespace chrome {
ChromeContentBrowserClient::ChromeContentBrowserClient() {
+#if defined(ENABLE_PLUGINS)
for (size_t i = 0; i < arraysize(kPredefinedAllowedSocketOrigins); ++i)
allowed_socket_origins_.insert(kPredefinedAllowedSocketOrigins[i]);
+#endif
permissions_policy_delegate_.reset(
new extensions::BrowserPermissionsPolicyDelegate());
@@ -2143,60 +2136,15 @@ bool ChromeContentBrowserClient::AllowPepperSocketAPI(
content::BrowserContext* browser_context,
const GURL& url,
const content::SocketPermissionRequest& params) {
- if (!url.is_valid())
- return false;
-
- std::string host = url.host();
- if (url.SchemeIs(extensions::kExtensionScheme) &&
- HostIsInSet(host, allowed_socket_origins_)) {
- return true;
- }
-
- Profile* profile = Profile::FromBrowserContext(browser_context);
- const Extension* extension = NULL;
- ExtensionService* extension_service = !profile ? NULL :
- extensions::ExtensionSystem::Get(profile)->extension_service();
- if (extension_service) {
- extension = extension_service->extensions()->
- GetExtensionOrAppByURL(ExtensionURLInfo(url));
- }
-
- // Check the modules that are imported by this extension to see if any of them
- // is whitelisted.
- if (extension) {
- const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
- extensions::SharedModuleInfo::GetImports(extension);
- std::vector<extensions::SharedModuleInfo::ImportInfo>::const_iterator it;
- for (it = imports.begin(); it != imports.end(); ++it) {
- const Extension* imported_extension = extension_service->
- GetExtensionById(it->extension_id, false);
- if (imported_extension &&
- extensions::SharedModuleInfo::IsSharedModule(imported_extension) &&
- HostIsInSet(it->extension_id, allowed_socket_origins_)) {
- return true;
- }
- }
- }
-
- // Need to check this now and not on construction because otherwise it won't
- // work with browser_tests.
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- std::string allowed_list =
- command_line.GetSwitchValueASCII(switches::kAllowNaClSocketAPI);
- if (allowed_list == "*") {
- // The wildcard allows socket API only for packaged and platform apps.
- return extension &&
- (extension->GetType() == Manifest::TYPE_LEGACY_PACKAGED_APP ||
- extension->GetType() == Manifest::TYPE_PLATFORM_APP);
- } else if (!allowed_list.empty()) {
- base::StringTokenizer t(allowed_list, ",");
- while (t.GetNext()) {
- if (t.token() == host)
- return true;
- }
- }
-
+#if defined(ENABLE_PLUGINS)
+ return IsExtensionOrSharedModuleWhitelisted(
+ Profile::FromBrowserContext(browser_context),
+ url,
+ allowed_socket_origins_,
+ switches::kAllowNaClSocketAPI);
+#else
return false;
+#endif
}
base::FilePath ChromeContentBrowserClient::GetHyphenDictionaryDirectory() {
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index 8cb0b83..6472748 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -22,7 +22,6 @@ class QuotaPermissionContext;
}
namespace extensions {
-class Extension;
class BrowserPermissionsPolicyDelegate;
}
@@ -257,8 +256,10 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient {
#endif
private:
+#if defined(ENABLE_PLUGINS)
// Set of origins that can use TCP/UDP private APIs from NaCl.
std::set<std::string> allowed_socket_origins_;
+#endif
scoped_ptr<extensions::BrowserPermissionsPolicyDelegate>
permissions_policy_delegate_;
diff --git a/chrome/browser/pepper_permission_util.cc b/chrome/browser/pepper_permission_util.cc
new file mode 100644
index 0000000..00976de
--- /dev/null
+++ b/chrome/browser/pepper_permission_util.cc
@@ -0,0 +1,103 @@
+// Copyright 2013 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/pepper_permission_util.h"
+
+#include <vector>
+
+#include "base/command_line.h"
+#include "base/sha1.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_tokenizer.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/google/google_util.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_set.h"
+#include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
+#include "extensions/common/constants.h"
+
+using extensions::Extension;
+using extensions::Manifest;
+
+namespace chrome {
+
+namespace {
+
+std::string HashHost(const std::string& host) {
+ const std::string id_hash = base::SHA1HashString(host);
+ DCHECK_EQ(id_hash.length(), base::kSHA1Length);
+ return base::HexEncode(id_hash.c_str(), id_hash.length());
+}
+
+bool HostIsInSet(const std::string& host, const std::set<std::string>& set) {
+ return set.count(host) > 0 || set.count(HashHost(host)) > 0;
+}
+
+} // namespace
+
+bool IsExtensionOrSharedModuleWhitelisted(
+ Profile* profile,
+ const GURL& url,
+ const std::set<std::string>& whitelist,
+ const char* command_line_switch) {
+ if (!url.is_valid())
+ return false;
+
+ const std::string host = url.host();
+ if (url.SchemeIs(extensions::kExtensionScheme) &&
+ HostIsInSet(host, whitelist)) {
+ return true;
+ }
+
+ const Extension* extension = NULL;
+ ExtensionService* extension_service = !profile ? NULL :
+ extensions::ExtensionSystem::Get(profile)->extension_service();
+ if (extension_service) {
+ extension = extension_service->extensions()->
+ GetExtensionOrAppByURL(ExtensionURLInfo(url));
+ }
+
+ // Check the modules that are imported by this extension to see if any of them
+ // is whitelisted.
+ if (extension) {
+ typedef std::vector<extensions::SharedModuleInfo::ImportInfo>
+ ImportInfoVector;
+ const ImportInfoVector& imports =
+ extensions::SharedModuleInfo::GetImports(extension);
+ for (ImportInfoVector::const_iterator it = imports.begin();
+ it != imports.end(); ++it) {
+ const Extension* imported_extension = extension_service->
+ GetExtensionById(it->extension_id, false);
+ if (imported_extension &&
+ extensions::SharedModuleInfo::IsSharedModule(imported_extension) &&
+ HostIsInSet(it->extension_id, whitelist)) {
+ return true;
+ }
+ }
+ }
+
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ const std::string allowed_list =
+ command_line.GetSwitchValueASCII(command_line_switch);
+ if (allowed_list == "*") {
+ // The wildcard allows socket API only for packaged and platform apps.
+ return extension &&
+ (extension->GetType() == Manifest::TYPE_LEGACY_PACKAGED_APP ||
+ extension->GetType() == Manifest::TYPE_PLATFORM_APP);
+ }
+
+ if (!allowed_list.empty()) {
+ base::StringTokenizer t(allowed_list, ",");
+ while (t.GetNext()) {
+ if (t.token() == host)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+} // namespace chrome
diff --git a/chrome/browser/pepper_permission_util.h b/chrome/browser/pepper_permission_util.h
new file mode 100644
index 0000000..a717b42
--- /dev/null
+++ b/chrome/browser/pepper_permission_util.h
@@ -0,0 +1,26 @@
+// Copyright 2013 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_PEPPER_PERMISSION_UTIL_H_
+#define CHROME_BROWSER_PEPPER_PERMISSION_UTIL_H_
+
+#include <set>
+#include <string>
+
+class GURL;
+class Profile;
+
+namespace chrome {
+
+// Returns true if the extension or it's shared module is whitelisted, or
+// appears in command_line_switch.
+bool IsExtensionOrSharedModuleWhitelisted(
+ Profile* profile,
+ const GURL& url,
+ const std::set<std::string>& whitelist,
+ const char* command_line_switch);
+
+} // namespace chrome
+
+#endif // CHROME_BROWSER_PEPPER_PERMISSION_UTIL_H_
diff --git a/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc b/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc
index 83434df..f7b48f7 100644
--- a/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc
+++ b/chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.cc
@@ -70,14 +70,6 @@ scoped_ptr<ResourceHost> ChromeBrowserPepperHostFactory::CreateResourceHost(
host_->GetPpapiHost(), instance, params.pp_resource(),
broker_filter));
}
- case PpapiHostMsg_Ext_CrxFileSystem_Create::ID: {
- PepperCrxFileSystemMessageFilter* crxfs_filter =
- PepperCrxFileSystemMessageFilter::Create(instance, host_);
- if (!crxfs_filter)
- return scoped_ptr<ResourceHost>();
- return scoped_ptr<ResourceHost>(new MessageFilterHost(
- host, instance, params.pp_resource(), crxfs_filter));
- }
case PpapiHostMsg_Talk_Create::ID:
return scoped_ptr<ResourceHost>(new PepperTalkHost(
host_, instance, params.pp_resource()));
@@ -103,6 +95,22 @@ scoped_ptr<ResourceHost> ChromeBrowserPepperHostFactory::CreateResourceHost(
host_, instance, params.pp_resource()));
}
}
+
+ // Permissions for the following interfaces will be checked at the
+ // time of the corresponding instance's methods calls (because
+ // permission check can be performed only on the UI
+ // thread). Currently these interfaces are available only for
+ // whitelisted apps which may not have access to the other private
+ // interfaces.
+ if (message.type() == PpapiHostMsg_Ext_CrxFileSystem_Create::ID) {
+ PepperCrxFileSystemMessageFilter* crxfs_filter =
+ PepperCrxFileSystemMessageFilter::Create(instance, host_);
+ if (!crxfs_filter)
+ return scoped_ptr<ResourceHost>();
+ return scoped_ptr<ResourceHost>(new MessageFilterHost(
+ host, instance, params.pp_resource(), crxfs_filter));
+ }
+
return scoped_ptr<ResourceHost>();
}
diff --git a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc
index 276b79d..67a3284 100644
--- a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc
+++ b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc
@@ -7,11 +7,14 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_system.h"
+#include "chrome/browser/pepper_permission_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "content/public/browser/browser_ppapi_host.h"
#include "content/public/browser/child_process_security_policy.h"
+#include "content/public/browser/render_view_host.h"
#include "extensions/common/constants.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/dispatch_host_message.h"
@@ -22,6 +25,14 @@
namespace chrome {
+namespace {
+
+const char* kPredefinedAllowedCrxFsOrigins[] = {
+ "6EAED1924DB611B6EEF2A664BD077BE7EAD33B8F" // see crbug.com/234789
+};
+
+} // namespace
+
// static
PepperCrxFileSystemMessageFilter* PepperCrxFileSystemMessageFilter::Create(
PP_Instance instance, content::BrowserPpapiHost* host) {
@@ -45,6 +56,8 @@ PepperCrxFileSystemMessageFilter::PepperCrxFileSystemMessageFilter(
: render_process_id_(render_process_id),
profile_directory_(profile_directory),
document_url_(document_url) {
+ for (size_t i = 0; i < arraysize(kPredefinedAllowedCrxFsOrigins); ++i)
+ allowed_crxfs_origins_.insert(kPredefinedAllowedCrxFsOrigins[i]);
}
PepperCrxFileSystemMessageFilter::~PepperCrxFileSystemMessageFilter() {
@@ -68,13 +81,14 @@ int32_t PepperCrxFileSystemMessageFilter::OnResourceMessageReceived(
return PP_ERROR_FAILED;
}
-std::string PepperCrxFileSystemMessageFilter::CreateIsolatedFileSystem() {
+Profile* PepperCrxFileSystemMessageFilter::GetProfile() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- if (!document_url_.SchemeIs(extensions::kExtensionScheme))
- return std::string();
-
ProfileManager* profile_manager = g_browser_process->profile_manager();
- Profile* profile = profile_manager->GetProfile(profile_directory_);
+ return profile_manager->GetProfile(profile_directory_);
+}
+
+std::string PepperCrxFileSystemMessageFilter::CreateIsolatedFileSystem(
+ Profile* profile) {
extensions::ExtensionSystem* extension_system =
extensions::ExtensionSystem::Get(profile);
if (!extension_system)
@@ -100,7 +114,16 @@ std::string PepperCrxFileSystemMessageFilter::CreateIsolatedFileSystem() {
int32_t PepperCrxFileSystemMessageFilter::OnOpenFileSystem(
ppapi::host::HostMessageContext* context) {
- const std::string fsid = CreateIsolatedFileSystem();
+ Profile* profile = GetProfile();
+ if (!IsExtensionOrSharedModuleWhitelisted(profile,
+ document_url_,
+ allowed_crxfs_origins_,
+ switches::kAllowNaClCrxFsAPI)) {
+ LOG(ERROR) << "Host " << document_url_.host() << " cannot use CrxFs API.";
+ return PP_ERROR_NOACCESS;
+ }
+
+ const std::string fsid = CreateIsolatedFileSystem(profile);
if (fsid.empty()) {
context->reply_msg =
PpapiPluginMsg_Ext_CrxFileSystem_BrowserOpenReply(std::string());
diff --git a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.h b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.h
index 53669e1..b970d11 100644
--- a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.h
+++ b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.h
@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_CRX_FILE_SYSTEM_MESSAGE_FILTER_H_
#define CHROME_BROWSER_RENDERER_HOST_PEPPER_PEPPER_CRX_FILE_SYSTEM_MESSAGE_FILTER_H_
+#include <set>
#include <string>
#include "base/files/file_path.h"
@@ -14,6 +15,8 @@
#include "ppapi/host/resource_host.h"
#include "ppapi/host/resource_message_filter.h"
+class Profile;
+
namespace content {
class BrowserPpapiHost;
}
@@ -48,10 +51,12 @@ class PepperCrxFileSystemMessageFilter
virtual ~PepperCrxFileSystemMessageFilter();
+ Profile* GetProfile();
+
// Returns filesystem id of isolated filesystem if valid, or empty string
// otherwise. This must run on the UI thread because ProfileManager only
// allows access on that thread.
- std::string CreateIsolatedFileSystem();
+ std::string CreateIsolatedFileSystem(Profile* profile);
int32_t OnOpenFileSystem(ppapi::host::HostMessageContext* context);
@@ -59,6 +64,9 @@ class PepperCrxFileSystemMessageFilter
const base::FilePath& profile_directory_;
const GURL document_url_;
+ // Set of origins that can use CrxFs private APIs from NaCl.
+ std::set<std::string> allowed_crxfs_origins_;
+
DISALLOW_COPY_AND_ASSIGN(PepperCrxFileSystemMessageFilter);
};
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 0011f12..979337d 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1280,6 +1280,8 @@
'browser/pepper_broker_infobar_delegate.h',
'browser/pepper_flash_settings_manager.cc',
'browser/pepper_flash_settings_manager.h',
+ 'browser/pepper_permission_util.cc',
+ 'browser/pepper_permission_util.h',
'browser/performance_monitor/constants.cc',
'browser/performance_monitor/constants.h',
'browser/performance_monitor/database.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index d0d5109..9ba69d2 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -44,6 +44,10 @@ const char kAllowLegacyExtensionManifests[] =
"allow-legacy-extension-manifests";
// Specifies comma-separated list of extension ids or hosts to grant
+// access to CRX file system APIs.
+const char kAllowNaClCrxFsAPI[] = "allow-nacl-crxfs-api";
+
+// Specifies comma-separated list of extension ids or hosts to grant
// access to TCP/UDP socket APIs.
const char kAllowNaClSocketAPI[] = "allow-nacl-socket-api";
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index 9610a1f..67f5516 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -30,6 +30,7 @@ extern const char kAllowFileAccess[];
extern const char kAllowHTTPBackgroundPage[];
extern const char kAllowHttpScreenCapture[];
extern const char kAllowLegacyExtensionManifests[];
+extern const char kAllowNaClCrxFsAPI[];
extern const char kAllowNaClSocketAPI[];
extern const char kAllowOutdatedPlugins[];
extern const char kAllowRunningInsecureContent[];
diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
index 4f586ca..3ed14d12 100644
--- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
+++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc
@@ -80,7 +80,7 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost(
// Permissions for the following interfaces will be checked at the
// time of the corresponding instance's methods calls (because
// permission check can be performed only on the UI
- // thread). Currently thise interfaces are available only for
+ // thread). Currently these interfaces are available only for
// whitelisted apps which may not have access to the other private
// interfaces.
if (message.type() == PpapiHostMsg_HostResolverPrivate_Create::ID) {