| Index: extensions/common/permissions/permissions_data.cc
|
| diff --git a/extensions/common/permissions/permissions_data.cc b/extensions/common/permissions/permissions_data.cc
|
| index 7fdbd2c36a79eea46b681b1f3ef464be2be27b15..6757298e4067268ba897e74a2bab1c5fa60ab538 100644
|
| --- a/extensions/common/permissions/permissions_data.cc
|
| +++ b/extensions/common/permissions/permissions_data.cc
|
| @@ -25,19 +25,31 @@ namespace {
|
|
|
| PermissionsData::PolicyDelegate* g_policy_delegate = NULL;
|
|
|
| +class AutoLockOnValidThread {
|
| + public:
|
| + AutoLockOnValidThread(base::Lock& lock, base::ThreadChecker* thread_checker)
|
| + : auto_lock_(lock) {
|
| + DCHECK(!thread_checker || thread_checker->CalledOnValidThread());
|
| + }
|
| +
|
| + private:
|
| + base::AutoLock auto_lock_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(AutoLockOnValidThread);
|
| +};
|
| +
|
| } // namespace
|
|
|
| PermissionsData::PermissionsData(const Extension* extension)
|
| : extension_id_(extension->id()), manifest_type_(extension->GetType()) {
|
| - base::AutoLock auto_lock(runtime_lock_);
|
| - scoped_refptr<const PermissionSet> required_permissions =
|
| + const PermissionSet* required_permissions =
|
| PermissionsParser::GetRequiredPermissions(extension);
|
| - active_permissions_unsafe_ =
|
| + active_permissions_unsafe_.reset(
|
| new PermissionSet(required_permissions->apis(),
|
| required_permissions->manifest_permissions(),
|
| required_permissions->explicit_hosts(),
|
| - required_permissions->scriptable_hosts());
|
| - withheld_permissions_unsafe_ = new PermissionSet();
|
| + required_permissions->scriptable_hosts()));
|
| + withheld_permissions_unsafe_.reset(new PermissionSet());
|
| }
|
|
|
| PermissionsData::~PermissionsData() {
|
| @@ -75,6 +87,7 @@ bool PermissionsData::ScriptsMayRequireActionForExtension(
|
| permissions->ShouldWarnAllHosts();
|
| }
|
|
|
| +// static
|
| bool PermissionsData::ShouldSkipPermissionWarnings(
|
| const std::string& extension_id) {
|
| // See http://b/4946060 for more details.
|
| @@ -121,60 +134,74 @@ bool PermissionsData::IsRestrictedUrl(const GURL& document_url,
|
| return false;
|
| }
|
|
|
| +void PermissionsData::BindToCurrentThread() const {
|
| + DCHECK(!thread_checker_);
|
| + thread_checker_.reset(new base::ThreadChecker());
|
| +}
|
| +
|
| void PermissionsData::SetPermissions(
|
| - const scoped_refptr<const PermissionSet>& active,
|
| - const scoped_refptr<const PermissionSet>& withheld) const {
|
| - base::AutoLock auto_lock(runtime_lock_);
|
| - active_permissions_unsafe_ = active;
|
| - withheld_permissions_unsafe_ = withheld;
|
| + scoped_ptr<const PermissionSet> active,
|
| + scoped_ptr<const PermissionSet> withheld) const {
|
| + AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
|
| + active_permissions_unsafe_ = active.Pass();
|
| + withheld_permissions_unsafe_ = withheld.Pass();
|
| +}
|
| +
|
| +void PermissionsData::SetActivePermissions(
|
| + scoped_ptr<const PermissionSet> active) const {
|
| + AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
|
| + active_permissions_unsafe_ = active.Pass();
|
| }
|
|
|
| void PermissionsData::UpdateTabSpecificPermissions(
|
| int tab_id,
|
| - scoped_refptr<const PermissionSet> permissions) const {
|
| - base::AutoLock auto_lock(runtime_lock_);
|
| + const PermissionSet& permissions) const {
|
| + AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
|
| CHECK_GE(tab_id, 0);
|
| - TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id);
|
| - if (iter == tab_specific_permissions_.end())
|
| - tab_specific_permissions_[tab_id] = permissions;
|
| - else
|
| - iter->second = PermissionSet::CreateUnion(*(iter->second), *permissions);
|
| + TabPermissionsMap::const_iterator iter =
|
| + tab_specific_permissions_.find(tab_id);
|
| + scoped_ptr<const PermissionSet> new_permissions = PermissionSet::CreateUnion(
|
| + iter == tab_specific_permissions_.end()
|
| + ? static_cast<const PermissionSet&>(PermissionSet())
|
| + : *iter->second,
|
| + permissions);
|
| + tab_specific_permissions_.set(tab_id, new_permissions.Pass());
|
| }
|
|
|
| void PermissionsData::ClearTabSpecificPermissions(int tab_id) const {
|
| - base::AutoLock auto_lock(runtime_lock_);
|
| + AutoLockOnValidThread lock(runtime_lock_, thread_checker_.get());
|
| CHECK_GE(tab_id, 0);
|
| tab_specific_permissions_.erase(tab_id);
|
| }
|
|
|
| bool PermissionsData::HasAPIPermission(APIPermission::ID permission) const {
|
| - return active_permissions()->HasAPIPermission(permission);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + return active_permissions_unsafe_->HasAPIPermission(permission);
|
| }
|
|
|
| bool PermissionsData::HasAPIPermission(
|
| const std::string& permission_name) const {
|
| - return active_permissions()->HasAPIPermission(permission_name);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + return active_permissions_unsafe_->HasAPIPermission(permission_name);
|
| }
|
|
|
| bool PermissionsData::HasAPIPermissionForTab(
|
| int tab_id,
|
| APIPermission::ID permission) const {
|
| - if (HasAPIPermission(permission))
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + if (active_permissions_unsafe_->HasAPIPermission(permission))
|
| return true;
|
|
|
| - scoped_refptr<const PermissionSet> tab_permissions =
|
| - GetTabSpecificPermissions(tab_id);
|
| -
|
| - // Place autolock below the HasAPIPermission() and
|
| - // GetTabSpecificPermissions(), since each already acquires the lock.
|
| - base::AutoLock auto_lock(runtime_lock_);
|
| - return tab_permissions.get() && tab_permissions->HasAPIPermission(permission);
|
| + const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id);
|
| + return tab_permissions && tab_permissions->HasAPIPermission(permission);
|
| }
|
|
|
| bool PermissionsData::CheckAPIPermissionWithParam(
|
| APIPermission::ID permission,
|
| const APIPermission::CheckParam* param) const {
|
| - return active_permissions()->CheckAPIPermissionWithParam(permission, param);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + return active_permissions_unsafe_->CheckAPIPermissionWithParam(permission,
|
| + param);
|
| }
|
|
|
| URLPatternSet PermissionsData::GetEffectiveHostPermissions() const {
|
| @@ -186,24 +213,28 @@ URLPatternSet PermissionsData::GetEffectiveHostPermissions() const {
|
| }
|
|
|
| bool PermissionsData::HasHostPermission(const GURL& url) const {
|
| - return active_permissions()->HasExplicitAccessToOrigin(url);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + return active_permissions_unsafe_->HasExplicitAccessToOrigin(url);
|
| }
|
|
|
| bool PermissionsData::HasEffectiveAccessToAllHosts() const {
|
| - return active_permissions()->HasEffectiveAccessToAllHosts();
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + return active_permissions_unsafe_->HasEffectiveAccessToAllHosts();
|
| }
|
|
|
| PermissionMessages PermissionsData::GetPermissionMessages() const {
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| return PermissionMessageProvider::Get()->GetPermissionMessages(
|
| PermissionMessageProvider::Get()->GetAllPermissionIDs(
|
| - active_permissions().get(), manifest_type_));
|
| + active_permissions_unsafe_.get(), manifest_type_));
|
| }
|
|
|
| bool PermissionsData::HasWithheldImpliedAllHosts() const {
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| // Since we currently only withhold all_hosts, it's sufficient to check
|
| // that either set is not empty.
|
| - return !withheld_permissions()->explicit_hosts().is_empty() ||
|
| - !withheld_permissions()->scriptable_hosts().is_empty();
|
| + return !withheld_permissions_unsafe_->explicit_hosts().is_empty() ||
|
| + !withheld_permissions_unsafe_->scriptable_hosts().is_empty();
|
| }
|
|
|
| bool PermissionsData::CanAccessPage(const Extension* extension,
|
| @@ -211,13 +242,11 @@ bool PermissionsData::CanAccessPage(const Extension* extension,
|
| int tab_id,
|
| int process_id,
|
| std::string* error) const {
|
| - AccessType result = CanRunOnPage(extension,
|
| - document_url,
|
| - tab_id,
|
| - process_id,
|
| - active_permissions()->explicit_hosts(),
|
| - withheld_permissions()->explicit_hosts(),
|
| - error);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + AccessType result =
|
| + CanRunOnPage(extension, document_url, tab_id, process_id,
|
| + active_permissions_unsafe_->explicit_hosts(),
|
| + withheld_permissions_unsafe_->explicit_hosts(), error);
|
| // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED.
|
| return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD;
|
| }
|
| @@ -228,13 +257,10 @@ PermissionsData::AccessType PermissionsData::GetPageAccess(
|
| int tab_id,
|
| int process_id,
|
| std::string* error) const {
|
| - return CanRunOnPage(extension,
|
| - document_url,
|
| - tab_id,
|
| - process_id,
|
| - active_permissions()->explicit_hosts(),
|
| - withheld_permissions()->explicit_hosts(),
|
| - error);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + return CanRunOnPage(extension, document_url, tab_id, process_id,
|
| + active_permissions_unsafe_->explicit_hosts(),
|
| + withheld_permissions_unsafe_->explicit_hosts(), error);
|
| }
|
|
|
| bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension,
|
| @@ -242,13 +268,11 @@ bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension,
|
| int tab_id,
|
| int process_id,
|
| std::string* error) const {
|
| - AccessType result = CanRunOnPage(extension,
|
| - document_url,
|
| - tab_id,
|
| - process_id,
|
| - active_permissions()->scriptable_hosts(),
|
| - withheld_permissions()->scriptable_hosts(),
|
| - error);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + AccessType result =
|
| + CanRunOnPage(extension, document_url, tab_id, process_id,
|
| + active_permissions_unsafe_->scriptable_hosts(),
|
| + withheld_permissions_unsafe_->scriptable_hosts(), error);
|
| // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED.
|
| return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD;
|
| }
|
| @@ -259,13 +283,10 @@ PermissionsData::AccessType PermissionsData::GetContentScriptAccess(
|
| int tab_id,
|
| int process_id,
|
| std::string* error) const {
|
| - return CanRunOnPage(extension,
|
| - document_url,
|
| - tab_id,
|
| - process_id,
|
| - active_permissions()->scriptable_hosts(),
|
| - withheld_permissions()->scriptable_hosts(),
|
| - error);
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + return CanRunOnPage(extension, document_url, tab_id, process_id,
|
| + active_permissions_unsafe_->scriptable_hosts(),
|
| + withheld_permissions_unsafe_->scriptable_hosts(), error);
|
| }
|
|
|
| bool PermissionsData::CanCaptureVisiblePage(int tab_id,
|
| @@ -273,13 +294,13 @@ bool PermissionsData::CanCaptureVisiblePage(int tab_id,
|
| const URLPattern all_urls(URLPattern::SCHEME_ALL,
|
| URLPattern::kAllUrlsPattern);
|
|
|
| - if (active_permissions()->explicit_hosts().ContainsPattern(all_urls))
|
| + base::AutoLock auto_lock(runtime_lock_);
|
| + if (active_permissions_unsafe_->explicit_hosts().ContainsPattern(all_urls))
|
| return true;
|
|
|
| if (tab_id >= 0) {
|
| - scoped_refptr<const PermissionSet> tab_permissions =
|
| - GetTabSpecificPermissions(tab_id);
|
| - if (tab_permissions.get() &&
|
| + const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id);
|
| + if (tab_permissions &&
|
| tab_permissions->HasAPIPermission(APIPermission::kTab)) {
|
| return true;
|
| }
|
| @@ -293,28 +314,22 @@ bool PermissionsData::CanCaptureVisiblePage(int tab_id,
|
| return false;
|
| }
|
|
|
| -PermissionsData::TabPermissionsMap
|
| -PermissionsData::CopyTabSpecificPermissionsMap() const {
|
| - base::AutoLock auto_lock(runtime_lock_);
|
| - return tab_specific_permissions_;
|
| -}
|
| -
|
| -scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions(
|
| +const PermissionSet* PermissionsData::GetTabSpecificPermissions(
|
| int tab_id) const {
|
| - base::AutoLock auto_lock(runtime_lock_);
|
| CHECK_GE(tab_id, 0);
|
| + runtime_lock_.AssertAcquired();
|
| TabPermissionsMap::const_iterator iter =
|
| tab_specific_permissions_.find(tab_id);
|
| - return (iter != tab_specific_permissions_.end()) ? iter->second : NULL;
|
| + return (iter != tab_specific_permissions_.end()) ? iter->second : nullptr;
|
| }
|
|
|
| bool PermissionsData::HasTabSpecificPermissionToExecuteScript(
|
| int tab_id,
|
| const GURL& url) const {
|
| + runtime_lock_.AssertAcquired();
|
| if (tab_id >= 0) {
|
| - scoped_refptr<const PermissionSet> tab_permissions =
|
| - GetTabSpecificPermissions(tab_id);
|
| - if (tab_permissions.get() &&
|
| + const PermissionSet* tab_permissions = GetTabSpecificPermissions(tab_id);
|
| + if (tab_permissions &&
|
| tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) {
|
| return true;
|
| }
|
| @@ -330,6 +345,7 @@ PermissionsData::AccessType PermissionsData::CanRunOnPage(
|
| const URLPatternSet& permitted_url_patterns,
|
| const URLPatternSet& withheld_url_patterns,
|
| std::string* error) const {
|
| + runtime_lock_.AssertAcquired();
|
| if (g_policy_delegate &&
|
| !g_policy_delegate->CanExecuteScriptOnPage(
|
| extension, document_url, tab_id, process_id, error)) {
|
|
|