summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/child_process_security_policy_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/child_process_security_policy_impl.h')
-rw-r--r--chromium/content/browser/child_process_security_policy_impl.h180
1 files changed, 144 insertions, 36 deletions
diff --git a/chromium/content/browser/child_process_security_policy_impl.h b/chromium/content/browser/child_process_security_policy_impl.h
index 9dbc29b83e7..93af81e6818 100644
--- a/chromium/content/browser/child_process_security_policy_impl.h
+++ b/chromium/content/browser/child_process_security_policy_impl.h
@@ -20,6 +20,7 @@
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
+#include "content/browser/isolation_context.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/common/resource_type.h"
#include "storage/common/fileapi/file_system_types.h"
@@ -42,6 +43,7 @@ class FileSystemURL;
namespace content {
+class IsolationContext;
class SiteInstance;
class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
@@ -96,15 +98,44 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
bool HasWebUIBindings(int child_id) override;
void GrantSendMidiSysExMessage(int child_id) override;
bool CanAccessDataForOrigin(int child_id, const GURL& url) override;
- bool GetMatchingIsolatedOrigin(const url::Origin& origin,
- url::Origin* result) override;
+
+ // This function will check whether |origin| requires process isolation
+ // within |isolation_context|, and if so, it will return true and put the
+ // most specific matching isolated origin into |result|.
+ //
+ // Such origins may be registered with the --isolate-origins command-line
+ // flag, via features::IsolateOrigins, via an IsolateOrigins enterprise
+ // policy, or by a content/ embedder using
+ // ContentBrowserClient::GetOriginsRequiringDedicatedProcess().
+ //
+ // If |origin| does not require process isolation, this function will return
+ // false, and |result| will be a unique origin. This means that neither
+ // |origin|, nor any origins for which |origin| is a subdomain, have been
+ // registered as isolated origins.
+ //
+ // For example, if both https://isolated.com/ and
+ // https://bar.foo.isolated.com/ are registered as isolated origins, then the
+ // values returned in |result| are:
+ // https://isolated.com/ --> https://isolated.com/
+ // https://foo.isolated.com/ --> https://isolated.com/
+ // https://bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
+ // https://baz.bar.foo.isolated.com/ --> https://bar.foo.isolated.com/
+ // https://unisolated.com/ --> (unique origin)
+ //
+ // |isolation_context| is used to determine which origins are isolated in
+ // this context. For example, isolated origins that are dynamically added
+ // will only affect future BrowsingInstances.
+ bool GetMatchingIsolatedOrigin(const IsolationContext& isolation_context,
+ const url::Origin& origin,
+ url::Origin* result);
// A version of GetMatchingIsolatedOrigin that takes in both the |origin| and
// the |site_url| that |origin| corresponds to. |site_url| is the key by
- // which |origin| will be looked up in |isolated_origins_|; this function
- // allows it to be passed in when it is already known to avoid recomputing it
- // internally.
- bool GetMatchingIsolatedOrigin(const url::Origin& origin,
+ // which |origin| will be looked up in |isolated_origins_| within
+ // |isolation_context|; this function allows it to be passed in when it is
+ // already known to avoid recomputing it internally.
+ bool GetMatchingIsolatedOrigin(const IsolationContext& isolation_context,
+ const url::Origin& origin,
const GURL& site_url,
url::Origin* result);
@@ -137,14 +168,15 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// this method exactly once.
void Add(int child_id);
- // Upon creation, worker thread child processes should register themselves by
- // calling this this method exactly once. Workers that are not shared will
- // inherit permissions from their parent renderer process identified with
- // |main_render_process_id|.
- void AddWorker(int worker_child_id, int main_render_process_id);
-
- // Upon destruction, child processess should unregister themselves by caling
+ // Upon destruction, child processes should unregister themselves by calling
// this method exactly once.
+ //
+ // Note: Pre-Remove() permissions remain in effect on the IO thread until
+ // the task posted to the IO thread by this call runs and removes the entry
+ // from |pending_remove_state_|.
+ // This UI -> IO task sequence ensures that any pending tasks, on the IO
+ // thread, for this |child_id| are allowed to run before access is completely
+ // revoked.
void Remove(int child_id);
// Whenever the browser processes commands the child process to commit a URL,
@@ -207,10 +239,16 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// Returns true if the specified child_id has been granted ReadRawCookies.
bool CanReadRawCookies(int child_id);
- // Sets the process as only permitted to use and see the cookies for the
- // given origin. Most callers should use RenderProcessHostImpl::LockToOrigin
- // instead of calling this directly.
- void LockToOrigin(int child_id, const GURL& lock_url);
+ // Sets the process identified by |child_id| as only permitted to access data
+ // for the origin specified by |lock_url|. Most callers should use
+ // RenderProcessHostImpl::LockToOrigin instead of calling this directly.
+ // |isolation_context| provides the context, such as BrowsingInstance, from
+ // which this process was locked to origin. This information is used when
+ // making isolation decisions for this process, such as determining which
+ // isolated origins pertain to it.
+ void LockToOrigin(const IsolationContext& isolation_context,
+ int child_id,
+ const GURL& lock_url);
// Used to indicate the result of comparing a process's origin lock to
// another value:
@@ -242,10 +280,10 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// Returns true if sending system exclusive messages is allowed.
bool CanSendMidiSysExMessage(int child_id);
- // Add |origins| to the list of origins that require process isolation.
- // When making process model decisions for such origins, the full
- // scheme+host+port tuple rather than scheme and eTLD+1 will be used.
- // SiteInstances for these origins will also use the full origin as site URL.
+ // Add |origins| to the list of origins that require process isolation. When
+ // making process model decisions for such origins, the scheme+host tuple
+ // rather than scheme and eTLD+1 will be used. SiteInstances for these
+ // origins will also use the full host of the isolated origin as site URL.
//
// Subdomains of an isolated origin are considered to be part of that
// origin's site. For example, if https://isolated.foo.com is added as an
@@ -264,9 +302,20 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
//
// Note that it is okay if |origins| contains duplicates - the set of origins
// will be deduplicated inside the method.
+ //
+ // The new isolated origins will apply only to BrowsingInstances and renderer
+ // processes created *after* this call. This is necessary to not break
+ // scripting relationships between same-origin iframes in existing
+ // BrowsingInstances. To do this, this function internally determines a
+ // threshold BrowsingInstance ID that is higher than all existing
+ // BrowsingInstance IDs but lower than future BrowsingInstance IDs, and
+ // associates it with each of the |origins|. If an origin had already been
+ // isolated prior to calling this, it is ignored, and its threshold is not
+ // updated.
void AddIsolatedOrigins(std::vector<url::Origin> origins);
- // Check whether |origin| requires origin-wide process isolation.
+ // Check whether |origin| requires origin-wide process isolation within
+ // |isolation_context|.
//
// Subdomains of an isolated origin are considered part of that isolated
// origin. Thus, if https://isolated.foo.com/ had been added as an isolated
@@ -274,9 +323,11 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// https://bar.isolated.foo.com/, or https://baz.bar.isolated.foo.com/; and
// it will return false for https://foo.com/ or https://unisolated.foo.com/.
//
- // Note that unlike site URLs for regular web sites, isolated origins care
- // about port.
- bool IsIsolatedOrigin(const url::Origin& origin);
+ // |isolation_context| is used to determine which origins are isolated in
+ // this context. For example, isolated origins that are dynamically added
+ // will only affect future BrowsingInstances.
+ bool IsIsolatedOrigin(const IsolationContext& isolation_context,
+ const url::Origin& origin);
// Removes a previously added isolated origin, currently only used in tests.
//
@@ -298,14 +349,49 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
NoLeak);
FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, FilePermissions);
FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, AddIsolatedOrigins);
+ FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
+ DynamicIsolatedOrigins);
class SecurityState;
typedef std::set<std::string> SchemeSet;
typedef std::map<int, std::unique_ptr<SecurityState>> SecurityStateMap;
- typedef std::map<int, int> WorkerToMainProcessMap;
typedef std::map<storage::FileSystemType, int> FileSystemPermissionPolicyMap;
+ // This struct holds an isolated origin along with information such as which
+ // BrowsingInstances it applies to. See |isolated_origins_| below for more
+ // details.
+ struct CONTENT_EXPORT IsolatedOriginEntry {
+ IsolatedOriginEntry(const url::Origin& origin,
+ BrowsingInstanceId min_browsing_instance_id);
+ // Copyable and movable.
+ IsolatedOriginEntry(const IsolatedOriginEntry& other);
+ IsolatedOriginEntry& operator=(const IsolatedOriginEntry& other);
+ IsolatedOriginEntry(IsolatedOriginEntry&& other);
+ IsolatedOriginEntry& operator=(IsolatedOriginEntry&& other);
+ ~IsolatedOriginEntry();
+
+ // Allow this class to be used as a key in STL.
+ bool operator<(const IsolatedOriginEntry& other) const {
+ return std::tie(origin, min_browsing_instance_id) <
+ std::tie(other.origin, other.min_browsing_instance_id);
+ }
+
+ bool operator==(const IsolatedOriginEntry& other) const {
+ return origin == other.origin &&
+ min_browsing_instance_id == other.min_browsing_instance_id;
+ }
+
+ url::Origin origin;
+ BrowsingInstanceId min_browsing_instance_id;
+ // TODO(alexmos): Track the source of each isolated origin entry, e.g., to
+ // distinguish those that should be displayed to the user from those that
+ // should not. See https://crbug.com/920911.
+ //
+ // TODO(alexmos): Add a way to associate isolated origin entries with
+ // profiles. See https://crbug.com/905513.
+ };
+
// Obtain an instance of ChildProcessSecurityPolicyImpl via GetInstance().
ChildProcessSecurityPolicyImpl();
friend struct base::DefaultSingletonTraits<ChildProcessSecurityPolicyImpl>;
@@ -335,9 +421,7 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
int permission);
// Determines if certain permissions were granted for a file. |permissions|
- // is an internally defined bit-set. If |child_id| is a worker process,
- // this returns true if either the worker process or its parent renderer
- // has permissions for the file.
+ // is an internally defined bit-set.
bool HasPermissionsForFile(int child_id,
const base::FilePath& file,
int permissions);
@@ -356,8 +440,14 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
const std::string& filesystem_id,
int permission);
+ // Gets the SecurityState object associated with |child_id|.
+ // Note: Returned object is only valid for the duration the caller holds
+ // |lock_|.
+ SecurityState* GetSecurityState(int child_id) EXCLUSIVE_LOCKS_REQUIRED(lock_);
+
// You must acquire this lock before reading or writing any members of this
- // class. You must not block while holding this lock.
+ // class, except for isolated_origins_ which uses its own lock. You must not
+ // block while holding this lock.
base::Lock lock_;
// These schemes are white-listed for all child processes in various contexts.
@@ -377,16 +467,27 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// not escape this class.
SecurityStateMap security_state_ GUARDED_BY(lock_);
- // This maps keeps the record of which js worker thread child process
- // corresponds to which main js thread child process.
- WorkerToMainProcessMap worker_map_ GUARDED_BY(lock_);
+ // This map holds the SecurityState for a child process after Remove()
+ // is called on the UI thread. An entry stays in this map until a task has
+ // run on the IO thread. This is necessary to provide consistent security
+ // decisions and avoid races between the UI & IO threads during child process
+ // shutdown. This separate map is used to preserve SecurityState info AND
+ // preventing mutation of that state after Remove() is called.
+ SecurityStateMap pending_remove_state_ GUARDED_BY(lock_);
FileSystemPermissionPolicyMap file_system_policy_map_ GUARDED_BY(lock_);
+ // You must acquire this lock before reading or writing isolated_origins_.
+ // You must not block while holding this lock.
+ //
+ // It is allowed to hold both |lock_| and |isolated_origins_lock_|, but in
+ // this case, |lock_| should always be acquired first to prevent deadlock.
+ base::Lock isolated_origins_lock_ ACQUIRED_AFTER(lock_);
+
// Tracks origins for which the entire origin should be treated as a site
// when making process model decisions, rather than the origin's scheme and
// eTLD+1. Each of these origins requires a dedicated process. This set is
- // protected by |lock_|.
+ // protected by |isolated_origins_lock_|.
//
// The origins are stored in a map indexed by a site URL computed for each
// origin. For example, adding https://foo.com, https://bar.foo.com, and
@@ -397,8 +498,15 @@ class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
// found in O(log n) time, and the corresponding list of origins to search
// using the expensive DoesOriginMatchIsolatedOrigin() comparison is
// typically small.
- base::flat_map<GURL, base::flat_set<url::Origin>> isolated_origins_
- GUARDED_BY(lock_);
+ //
+ // Each origin also stores information about which BrowsingInstances it
+ // applies to, in the form of a minimum BrowsingInstance ID. This is looked
+ // up at the time the isolated origin is added. The isolated origin will
+ // apply only to future BrowsingInstances, which will have IDs equal to or
+ // greater than the threshold ID (called |min_browsing_instance_id|) in each
+ // origin's IsolatedOriginEntry.
+ base::flat_map<GURL, base::flat_set<IsolatedOriginEntry>> isolated_origins_
+ GUARDED_BY(isolated_origins_lock_);
DISALLOW_COPY_AND_ASSIGN(ChildProcessSecurityPolicyImpl);
};