// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_
#define CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_

#include <map>
#include <memory>
#include <set>
#include <string>
#include <string_view>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/singleton.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "content/browser/can_commit_status.h"
#include "content/browser/isolated_origin_util.h"
#include "content/browser/isolation_context.h"
#include "content/browser/origin_agent_cluster_isolation_state.h"
#include "content/common/content_export.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/common/bindings_policy.h"
#include "storage/common/file_system/file_system_types.h"
#include "url/origin.h"

class GURL;

namespace base {
class FilePath;
}  // namespace base

namespace network {
class ResourceRequestBody;
}  // namespace network

namespace storage {
class FileSystemContext;
class FileSystemURL;
}  // namespace storage

namespace content {

class BrowserContext;
class IsolationContext;
class ProcessLock;
class ResourceContext;
struct UrlInfo;

class CONTENT_EXPORT ChildProcessSecurityPolicyImpl
    : public ChildProcessSecurityPolicy {
 public:
  // Handle used to access the security state for a specific process.
  //
  // Objects that require the security state to be preserved beyond the
  // lifetime of the RenderProcessHostImpl should hold an instance of this
  // object and use it to answer security policy questions. (e.g. Mojo services
  // created by RPHI that can receive calls after RPHI destruction). This
  // object should only be called on the UI and IO threads.
  //
  // Note: Some security methods, like CanAccessDataForOrigin(), require
  // information from the BrowserContext to make its decisions. These methods
  // will fall back to failsafe values if called after BrowserContext
  // destruction. Callers should be prepared to gracefully handle this or
  // ensure that they don't make any calls after BrowserContext destruction.
  class CONTENT_EXPORT Handle {
   public:
    Handle();
    Handle(Handle&&);
    Handle(const Handle&) = delete;
    ~Handle();

    Handle& operator=(const Handle&) = delete;
    Handle& operator=(Handle&&);

    // Create a new instance of Handle, holding another reference to the same
    // process ID as the current one.
    Handle Duplicate();

    // Returns true if this object has a valid process ID.
    // Returns false if this object was created with the default constructor,
    // the contents of this object was transferred to another Handle via
    // std::move(), or ChildProcessSecurityPolicyImpl::CreateHandle()
    // created this object after the process has already been destructed.
    bool is_valid() const;

    // Before servicing a child process's request to upload a file to the web,
    // the browser should call this method to determine whether the process has
    // the capability to upload the requested file.
    bool CanReadFile(const base::FilePath& file);

    // Explicit read permissions check for FileSystemURL specified files.
    bool CanReadFileSystemFile(const storage::FileSystemURL& url);

    // Returns true if the process is permitted to read and modify the data for
    // the given `origin`. For more details, see
    // ChildProcessSecurityPolicy::CanAccessDataForOrigin().
    bool CanAccessDataForOrigin(const url::Origin& origin);

    // Returns the original `child_id` used to create the handle.
    int child_id() { return child_id_; }

   private:
    friend class ChildProcessSecurityPolicyImpl;
    // |child_id| - The ID of the process that this Handle is being created
    // for, or ChildProcessHost::kInvalidUniqueID if an invalid handle is being
    // created.
    // |duplicating_handle| - True if the handle is being created by a
    // Duplicate() call. Otherwise false. This is used to trigger special
    // behavior for handle duplication that is not allowed for Handles created
    // by other means.
    Handle(int child_id, bool duplicating_handle);

    // The ID of the child process that this handle is associated with or
    // ChildProcessHost::kInvalidUniqueID if the handle is no longer valid.
    int child_id_;
  };

  ChildProcessSecurityPolicyImpl(const ChildProcessSecurityPolicyImpl&) =
      delete;
  ChildProcessSecurityPolicyImpl& operator=(
      const ChildProcessSecurityPolicyImpl&) = delete;

  // Object can only be created through GetInstance() so the constructor is
  // private.
  ~ChildProcessSecurityPolicyImpl() override;

  static ChildProcessSecurityPolicyImpl* GetInstance();

  // ChildProcessSecurityPolicy implementation.
  void RegisterWebSafeScheme(const std::string& scheme) override;
  void RegisterWebSafeIsolatedScheme(
      const std::string& scheme,
      bool always_allow_in_origin_headers) override;
  bool IsWebSafeScheme(const std::string& scheme) override;
  void GrantReadFile(int child_id, const base::FilePath& file) override;
  void GrantCreateReadWriteFile(int child_id,
                                const base::FilePath& file) override;
  void GrantCopyInto(int child_id, const base::FilePath& dir) override;
  void GrantDeleteFrom(int child_id, const base::FilePath& dir) override;
  void GrantReadFileSystem(int child_id,
                           const std::string& filesystem_id) override;
  void GrantWriteFileSystem(int child_id,
                            const std::string& filesystem_id) override;
  void GrantCreateFileForFileSystem(int child_id,
                                    const std::string& filesystem_id) override;
  void GrantCreateReadWriteFileSystem(
      int child_id,
      const std::string& filesystem_id) override;
  void GrantCopyIntoFileSystem(int child_id,
                               const std::string& filesystem_id) override;
  void GrantDeleteFromFileSystem(int child_id,
                                 const std::string& filesystem_id) override;
  void GrantCommitOrigin(int child_id, const url::Origin& origin) override;
  void GrantRequestOrigin(int child_id, const url::Origin& origin) override;
  void GrantRequestScheme(int child_id, const std::string& scheme) override;
  bool CanRequestURL(int child_id, const GURL& url) override;
  bool CanReadFile(int child_id, const base::FilePath& file) override;
  bool CanCreateReadWriteFile(int child_id,
                              const base::FilePath& file) override;
  bool CanReadFileSystem(int child_id,
                         const std::string& filesystem_id) override;
  bool CanReadWriteFileSystem(int child_id,
                              const std::string& filesystem_id) override;
  bool CanCopyIntoFileSystem(int child_id,
                             const std::string& filesystem_id) override;
  bool CanDeleteFromFileSystem(int child_id,
                               const std::string& filesystem_id) override;
  bool HasWebUIBindings(int child_id) override;
  void GrantSendMidiMessage(int child_id) override;
  void GrantSendMidiSysExMessage(int child_id) override;
  bool CanAccessDataForOrigin(int child_id, const url::Origin& origin) override;
  bool HostsOrigin(int child_id, const url::Origin& origin) override;
  void AddFutureIsolatedOrigins(
      std::string_view origins_list,
      IsolatedOriginSource source,
      BrowserContext* browser_context = nullptr) override;
  void AddFutureIsolatedOrigins(
      const std::vector<url::Origin>& origins,
      IsolatedOriginSource source,
      BrowserContext* browser_context = nullptr) override;
  bool IsGloballyIsolatedOriginForTesting(const url::Origin& origin) override;
  std::vector<url::Origin> GetIsolatedOrigins(
      std::optional<IsolatedOriginSource> source = std::nullopt,
      BrowserContext* browser_context = nullptr) override;
  bool IsIsolatedSiteFromSource(const url::Origin& origin,
                                IsolatedOriginSource source) override;
  void ClearIsolatedOriginsForTesting() override;

  // Centralized internal implementation of site isolation enforcements,
  // including CanAccessDataForOrigin and HostsOrigin. It supports the following
  // types of access checks, in order of increasing strictness:
  enum class AccessType {
    // Whether the process can commit a navigation to an origin, allowing a
    // document with that origin to be hosted in this process. This is
    // specifically about whether a particular new origin may be introduced
    // into a given process.
    kCanCommitNewOrigin,
    // Whether the process has previously committed a document or instantiated a
    // worker with the particular origin. This can be used to verify whether a
    // particular origin can be used as an initiator or source origin, e.g. in
    // postMessage or other IPCs sent from this process. Unlike
    // kCanCommitNewOrigin, this check assumes that the origin must already
    // exist in the process. Because a document/worker destruction may race with
    // processing legitimate IPCs on behalf of `origin`, this check also allows
    // the case where an origin has been hosted by the process in the past, but
    // not necessarily now.
    kHostsOrigin,
    // Whether the process can access data belonging to an origin already
    // committed in the process, such as passwords, localStorage, or cookies.
    // Similarly to kHostsOrigin, this check assumes that the origin must
    // already
    // exist in the process, but it is more strict for certain kinds of
    // processes that aren't supposed to access any data. For example, sandboxed
    // frame processes (which contain only opaque origins) or PDF processes
    // cannot access data for any origin.
    kCanAccessDataForCommittedOrigin,
  };
  bool CanAccessOrigin(int child_id,
                       const url::Origin& origin,
                       AccessType access_type);

  // Determines if the combination of origin, url and web_exposed_isolation_info
  // bundled in `url_info` are safe to commit to the process associated with
  // `child_id`.
  //
  // Returns CAN_COMMIT_ORIGIN_AND_URL if it is safe to commit `url_info` origin
  // and `url_info`'s url combination to the process associated with `child_id`.
  // Returns CANNOT_COMMIT_URL if `url_info` url is not safe to commit.
  // Returns CANNOT_COMMIT_ORIGIN if `url_info` origin is not safe to commit.
  CanCommitStatus CanCommitOriginAndUrl(
      int child_id,
      const IsolationContext& isolation_context,
      const UrlInfo& url_info);

  // Whether the process is allowed to commit a document from the given URL.
  // This is more restrictive than CanRequestURL, since CanRequestURL allows
  // requests that might lead to cross-process navigations or external protocol
  // handlers. Used primarily as a helper for CanCommitOriginAndUrl and thus not
  // exposed publicly.
  bool CanCommitURL(int child_id, const GURL& url);

  // 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 GetMatchingProcessIsolatedOrigin(
      const IsolationContext& isolation_context,
      const url::Origin& origin,
      bool requests_origin_keyed_process,
      url::Origin* result);

  // Removes any state associated with `browsing_instance_id`.
  void RemoveAllStateForBrowsingInstance(
      const BrowsingInstanceId& browsing_instance_id);

  // Registers |origin| isolation state in the BrowsingInstance associated
  // with |isolation_context|.
  //
  // |oac_isolation_state| is the Origin-Agent-Cluster to register for the
  // origin. It contains values describing both the logical isolation (i.e.
  // agent cluster separation in the renderer process) and the process isolation
  // that can be triggered by the Origin-Agent-Cluster header, the
  // kOriginKeyedProcessesByDefault feature and the
  // kOriginAgentClusterDefaultEnabled feature.
  //
  // If |origin| has already been registered as isolated for the same
  // BrowsingInstance, then nothing will be changed by this call.
  void AddOriginAgentClusterStateForBrowsingInstance(
      const IsolationContext& isolation_context,
      const url::Origin& origin,
      const OriginAgentClusterIsolationState& oac_isolation_state);

  // Adds `origin` to the IsolatedOrigins list for only the BrowsingInstance of
  // `isolation_context`, without isolating all subdomains. For use when the
  // isolation is triggered by COOP headers.
  void AddCoopIsolatedOriginForBrowsingInstance(
      const IsolationContext& isolation_context,
      const url::Origin& origin,
      IsolatedOriginSource source);

  // This function will check whether |origin| has opted-in to logical or
  // process isolation (via the Origin-Agent-Cluster header), with respect to
  // the current state of the |isolation_context|. It is different from
  // IsIsolatedOrigin() in that it only deals with Origin-Agent-Cluster
  // isolation status, whereas IsIsolatedOrigin() considers all possible
  // mechanisms for requesting isolation. It will check for two things:
  // 1) whether |origin| already is assigned to a SiteInstance in the
  //    |isolation_context| by being tracked in
  //    |origin_isolation_by_browsing_instance_|, in which case we follow the
  //    same policy, or
  // 2) if it's not currently tracked as described above, whether |origin| is
  //    currently requesting isolation via |requested_isolation_state|.
  OriginAgentClusterIsolationState DetermineOriginAgentClusterIsolation(
      const IsolationContext& isolation_context,
      const url::Origin& origin,
      const OriginAgentClusterIsolationState& requested_isolation_state);

  // This function adds |origin| to the master list of origins that have
  // ever requested opt-in isolation in the given |browser_context|, either via
  // an OriginPolicy or opt-in header. Returns true if |origin| is not already
  // in the list.
  bool UpdateOriginIsolationOptInListIfNecessary(
      BrowserContext* browser_context,
      const url::Origin& origin);

  // A version of GetMatchingProcessIsolatedOrigin 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_| within
  // |isolation_context|; this function allows it to be passed in when it is
  // already known to avoid recomputing it internally.
  bool GetMatchingProcessIsolatedOrigin(
      const IsolationContext& isolation_context,
      const url::Origin& origin,
      bool requests_origin_keyed_process,
      const GURL& site_url,
      url::Origin* result);

  // Stores the v8-optimization state for the passed-in `browsing_instance_id`
  // and `process_lock_origin` if the state isn't already cached.
  void AddV8OptimizationDisabledStateForOriginIfNotCached(
      const BrowsingInstanceId& browsing_instance_id,
      const url::Origin& process_lock_origin,
      bool are_v8_optimizations_disabled);

  // Returns whether v8-optimization should be disabled for the passed-in
  // (`browsing_instance_id`, `process_lock_origin`) pair. Returns std::nullopt
  // if there is no cached v8-optimization verdict.
  std::optional<bool> LookupAreV8OptimizationsDisabled(
      const BrowsingInstanceId& browsing_instance_id,
      const url::Origin& process_lock_origin);

  // Returns if |child_id| can read all of the |files|.
  bool CanReadAllFiles(int child_id, const std::vector<base::FilePath>& files);

  // Validate that |child_id| in |file_system_context| is allowed to access
  // data in the POST body specified by |body|.  Can be called on any thread.
  bool CanReadRequestBody(
      int child_id,
      const storage::FileSystemContext* file_system_context,
      const scoped_refptr<network::ResourceRequestBody>& body);

  // Validate that `process` is allowed to access data in the POST body
  // specified by |body|.  Has to be called on the UI thread.
  bool CanReadRequestBody(
      RenderProcessHost* process,
      const scoped_refptr<network::ResourceRequestBody>& body);

  // Pseudo schemes are treated differently than other schemes because they
  // cannot be requested like normal URLs.  There is no mechanism for revoking
  // pseudo schemes.
  void RegisterPseudoScheme(const std::string& scheme);

  // Returns true iff |scheme| has been registered as pseudo scheme.
  bool IsPseudoScheme(const std::string& scheme);

  // Upon creation, child processes should register themselves by calling this
  // this method exactly once. This call must be made on the UI thread.
  void Add(int child_id, BrowserContext* browser_context);

  // Helper method for unit tests that calls Add() and
  // LockProcess() with an "allow_any_site" lock. This ensures that the process
  // policy is always in a state where it is valid to call
  // CanAccessDataForOrigin().
  void AddForTesting(int child_id, BrowserContext* browser_context);

  // Upon destruction, child processes should unregister themselves by calling
  // this method exactly once. This call must be made on the UI thread.
  //
  // 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,
  // it should call this method to grant the child process the capability to
  // commit anything from the URL's origin, along with permission to request all
  // URLs of the same scheme.
  void GrantCommitURL(int child_id, const GURL& url);

  // Whenever the browser process drops a file icon on a tab, it should call
  // this method to grant the child process the capability to request this one
  // file:// URL (or content:// URL in android), but not all urls of the file://
  // scheme.
  void GrantRequestOfSpecificFile(int child_id, const base::FilePath& file);

  // Revokes all permissions granted to the given file.
  void RevokeAllPermissionsForFile(int child_id, const base::FilePath& file);

  // Grant the child process the ability to use Web UI Bindings.
  void GrantWebUIBindings(int child_id, BindingsPolicySet bindings);

  // Grant the child process the ability to read raw cookies.
  void GrantReadRawCookies(int child_id);

  // Revoke read raw cookies permission.
  void RevokeReadRawCookies(int child_id);

  // Some APIs for Android WebView and <webview> tags allow bypassing some
  // security checks, such as which URLs are allowed to commit. This method
  // grants that ability to any document with an origin used with these APIs,
  // because the exemption is needed for about:blank frames that inherit the
  // same origin.
  //
  // For safety, this is limited to opaque origins used with LoadDataWithBaseURL
  // in unlocked processes, as well as file origins used with
  // allow_universal_access_from_file_urls.
  //
  // Note that LoadDataWithBaseURL can be used with non-opaque origins as well,
  // but in that case the bypass is only allowed for the document and not the
  // entire origin, to prevent other code in the origin from bypassing checks.
  void GrantOriginCheckExemptionForWebView(int child_id,
                                           const url::Origin& origin);

  // Returns whether the given opaque or file origin was granted an exemption
  // due to Android WebView and <webview> APIs, allowing its documents to bypass
  // certain URL and origin checks.
  bool HasOriginCheckExemptionForWebView(int child_id,
                                         const url::Origin& origin);

  // Explicit permissions checks for FileSystemURL specified files.
  bool CanReadFileSystemFile(int child_id,
                             const storage::FileSystemURL& filesystem_url);
  bool CanWriteFileSystemFile(int child_id,
                              const storage::FileSystemURL& filesystem_url);
  bool CanCreateFileSystemFile(int child_id,
                               const storage::FileSystemURL& filesystem_url);
  bool CanCreateReadWriteFileSystemFile(
      int child_id,
      const storage::FileSystemURL& filesystem_url);
  bool CanCopyIntoFileSystemFile(int child_id,
                                 const storage::FileSystemURL& filesystem_url);
  bool CanDeleteFileSystemFile(int child_id,
                               const storage::FileSystemURL& filesystem_url);
  bool CanMoveFileSystemFile(int child_id,
                             const storage::FileSystemURL& src_url,
                             const storage::FileSystemURL& dest_url);
  bool CanCopyFileSystemFile(int child_id,
                             const storage::FileSystemURL& src_url,
                             const storage::FileSystemURL& dest_url);

  // Returns true if the specified child_id has been granted ReadRawCookies.
  bool CanReadRawCookies(int child_id);

  // Notifies security state of |child_id| about the IsolationContext it will
  // host.  The main side effect is proper setting of the lowest
  // BrowsingInstanceId associated with the security state.
  void IncludeIsolationContext(int child_id,
                               const IsolationContext& isolation_context);

  // Sets the process identified by |child_id| as only permitted to access data
  // for the origin specified by |site_info|'s process_lock_url(). Most callers
  // should use RenderProcessHostImpl::SetProcessLock instead of calling this
  // directly. |isolation_context| provides the context, such as
  // BrowsingInstance, from which this process locked was created. This
  // information is used when making isolation decisions for this process, such
  // as determining which isolated origins pertain to it. |is_process_used|
  // indicates whether any content has been loaded in the process already.
  void LockProcess(const IsolationContext& isolation_context,
                   int child_id,
                   bool is_process_used,
                   const ProcessLock& process_lock);

  // Testing helper method that generates a lock_url from |url| and then
  // calls LockProcess() with that lock URL.
  void LockProcessForTesting(const IsolationContext& isolation_context,
                             int child_id,
                             const GURL& url);

  // Retrieves the current ProcessLock of process |child_id|.  Returns an empty
  // lock if the process does not exist or if it is not locked.
  ProcessLock GetProcessLock(int child_id);

  // Register FileSystem type and permission policy which should be used
  // for the type.  The |policy| must be a bitwise-or'd value of
  // storage::FilePermissionPolicy.
  void RegisterFileSystemPermissionPolicy(storage::FileSystemType type,
                                          int policy);

  // Returns true if sending MIDI messages is allowed.
  bool CanSendMidiMessage(int child_id);

  // Returns true if sending system exclusive (SysEx) MIDI messages is allowed.
  bool CanSendMidiSysExMessage(int child_id);

  // Remove all isolated origins associated with |browser_context| and clear any
  // pointers that may reference |browser_context|.  This is
  // typically used when |browser_context| is being destroyed and assumes that
  // no processes are running or will run for that profile; this makes the
  // isolated origin removal safe.  Note that |browser_context| cannot be null;
  // i.e., isolated origins that apply globally to all profiles cannot
  // currently be removed, since that is not safe to do at runtime.
  void RemoveStateForBrowserContext(const BrowserContext& browser_context);

  // 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
  // origin, this will return true for https://isolated.foo.com/,
  // 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/.
  //
  // |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. |origin_requests_isolation| may
  // be true during navigation requests, and allows us to correctly determine
  // isolation status for an origin that may not have had its isolation status
  // recorded in the BrowsingInstance yet.
  bool IsIsolatedOrigin(const IsolationContext& isolation_context,
                        const url::Origin& origin,
                        bool origin_requests_isolation);

  // Removes a previously added isolated origin, currently only used in tests.
  //
  // TODO(alexmos): Exposing this more generally will require extra care, such
  // as ensuring that there are no active SiteInstances in that origin.
  void RemoveIsolatedOriginForTesting(const url::Origin& origin);

  // Returns false for redirects that must be blocked no matter which renderer
  // process initiated the request (if any).
  // Note: Checking CanRedirectToURL is not enough. CanRequestURL(child_id, url)
  //       represents a stricter subset. It must also be used for
  //       renderer-initiated navigations.
  bool CanRedirectToURL(const GURL& url);

  // Sets "killed_process_origin_lock" crash key with lock info for the
  // process associated with |child_id|.
  void LogKilledProcessOriginLock(int child_id);

  // Creates a Handle object for a specific child process ID.
  //
  // This handle can be used to extend the lifetime of policy state beyond
  // the Remove() call for |child_id|. This should be used by objects that can
  // outlive the RenderProcessHostImpl object associated with |child_id| and
  // need to be able to make policy decisions after RPHI destruction. (e.g.
  // Mojo services created by RPHI)
  //
  // Returns a valid Handle for any |child_id| that is present in
  // |security_state_|. Otherwise it returns a Handle that returns false for
  // all policy checks.
  Handle CreateHandle(int child_id);

  // Returns true if we have seen an explicit Origin-Agent-Cluster header
  // (either opt-in or opt-out) for this |origin| in the given |browser_context|
  // before in any BrowsingInstance.
  bool HasOriginEverRequestedOriginAgentClusterValue(
      BrowserContext* browser_context,
      const url::Origin& origin);

  // Adds |origin| to the opt-in-out list as having the default isolation state
  // for the BrowsingInstance specified by |isolation_context|, if we need to
  // track it and it's not already in the list.
  // |is_global_walk_or_frame_removal| should be set to true during the global
  // walk that is triggered when |origin| first requests opt-in isolation, so
  // that the function can skip safety checks that will be unnecessary during
  // the global walk. It is also set to true if this function is called when
  // removing a FrameNavigationEntry, since that entry won't be available to any
  // subsequent global walks.
  void AddDefaultIsolatedOriginIfNeeded(
      const IsolationContext& isolation_context,
      const url::Origin& origin,
      bool is_global_walk_or_frame_removal);

  // Add `origin` to the list of committed origins for the process identified by
  // `child_id`. An attempt to add the same origin more than once is safely
  // ignored. Note that there is currently no way to revoke an origin once it
  // has been committed, even if all associated documents and workers go away.
  // This might need to be revisited in the future if the list of committed
  // origins grows too large.
  void AddCommittedOrigin(int child_id, const url::Origin& origin);

  // Allows tests to modify the delay in cleaning up BrowsingInstanceIds. If the
  // delay is set to zero, cleanup happens immediately.
  void SetBrowsingInstanceCleanupDelayForTesting(int64_t delay_in_seconds) {
    browsing_instance_cleanup_delay_ = base::Seconds(delay_in_seconds);
  }

  // Allows tests to query the number of BrowsingInstanceIds associated with a
  // child process.
  size_t BrowsingInstanceIdCountForTesting(int child_id);

  void ClearRegisteredSchemeForTesting(const std::string& scheme);

  // Checks if the provided `url` matches any committed origin in the process
  // `child_id`. Currently only exposed for testing, since normally this check
  // happens within CanAccessMaybeOpaqueOrigin().
  bool MatchesCommittedOriginForTesting(int child_id,
                                        const GURL& url,
                                        bool url_is_for_precursor_origin);

  // Exposes LookupOriginIsolationState() for tests.
  OriginAgentClusterIsolationState* LookupOriginIsolationStateForTesting(
      const BrowsingInstanceId& browsing_instance_id,
      const url::Origin& origin);

 private:
  friend class ChildProcessSecurityPolicyInProcessBrowserTest;
  friend class ChildProcessSecurityPolicyTest;
  friend class ChildProcessSecurityPolicyImpl::Handle;
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyInProcessBrowserTest,
                           NoLeak);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, FilePermissions);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           AddFutureIsolatedOrigins);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           DynamicIsolatedOrigins);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           IsolatedOriginsForSpecificBrowserContexts);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           IsolatedOriginsForSpecificBrowsingInstances);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           IsolatedOriginsForCurrentAndFutureBrowsingInstances);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           IsolatedOriginsRemovedWhenBrowserContextDestroyed);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           IsolateAllSuborigins);
  FRIEND_TEST_ALL_PREFIXES(
      ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
      WildcardAndNonWildcardOrigins);
  FRIEND_TEST_ALL_PREFIXES(
      ChildProcessSecurityPolicyTest_NoOriginKeyedProcessesByDefault,
      WildcardAndNonWildcardEmbedded);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           ParseIsolatedOrigins);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest, WildcardDefaultPort);
  FRIEND_TEST_ALL_PREFIXES(ChildProcessSecurityPolicyTest,
                           MatchesCommittedOrigin);

  class SecurityState;

  typedef std::set<std::string> SchemeSet;
  typedef std::map<int, std::unique_ptr<SecurityState>> SecurityStateMap;
  typedef std::map<storage::FileSystemType, int> FileSystemPermissionPolicyMap;

  // This class holds an isolated origin along with information such as which
  // BrowsingInstances and profile it applies to.  See |isolated_origins_|
  // below for more details.
  class CONTENT_EXPORT IsolatedOriginEntry {
   public:
    IsolatedOriginEntry(const url::Origin& origin,
                        bool applies_to_future_browsing_instances,
                        BrowsingInstanceId browsing_instance_id,
                        BrowserContext* browser_context,
                        ResourceContext* resource_context,
                        bool isolate_all_subdomains,
                        IsolatedOriginSource source);
    // 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_, applies_to_future_browsing_instances_,
                      browsing_instance_id_, browser_context_,
                      resource_context_, isolate_all_subdomains_, source_) <
             std::tie(other.origin_,
                      other.applies_to_future_browsing_instances_,
                      other.browsing_instance_id_, other.browser_context_,
                      other.resource_context_, other.isolate_all_subdomains_,
                      source_);
    }

    bool operator==(const IsolatedOriginEntry& other) const {
      return origin_ == other.origin_ &&
             applies_to_future_browsing_instances_ ==
                 other.applies_to_future_browsing_instances_ &&
             browsing_instance_id_ == other.browsing_instance_id_ &&
             browser_context_ == other.browser_context_ &&
             resource_context_ == other.resource_context_ &&
             isolate_all_subdomains_ == other.isolate_all_subdomains_ &&
             source_ == other.source_;
    }

    // True if this isolated origin applies globally to all profiles.
    bool AppliesToAllBrowserContexts() const;

    // True if (1) this entry is associated with the same profile as
    // |browser_or_resource_context|, or (2) this entry applies to all
    // profiles.  May be used on UI or IO threads.
    bool MatchesProfile(
        const BrowserOrResourceContext& browser_or_resource_context) const;

    // True if this entry applies to the BrowsingInstance specified by
    // `browsing_instance_id`.  See `applies_to_future_browsing_instances_` and
    // `browsing_instance_id_` for more details.
    bool MatchesBrowsingInstance(BrowsingInstanceId browsing_instance_id) const;

    const url::Origin& origin() const { return origin_; }

    // See the declaration of `applies_to_future_browsing_instances_` for
    // details.
    bool applies_to_future_browsing_instances() const {
      return applies_to_future_browsing_instances_;
    }

    // See the declaration of `browsing_instance_id_` for details.
    BrowsingInstanceId browsing_instance_id() const {
      return browsing_instance_id_;
    }

    const BrowserContext* browser_context() const { return browser_context_; }

    bool isolate_all_subdomains() const { return isolate_all_subdomains_; }

    IsolatedOriginSource source() const { return source_; }

   private:
    url::Origin origin_;

    // If this is false, the origin is isolated only in the BrowsingInstance
    // specified by `browsing_instance_id_`.  If this is true, the origin is
    // isolated in all BrowsingInstances that have an ID equal to or
    // greater than `browsing_instance_id_`.
    bool applies_to_future_browsing_instances_;

    // Specifies which BrowsingInstance(s) this IsolatedOriginEntry applies to.
    // When `applies_to_future_browsing_instances_` is false, this refers to a
    // specific BrowsingInstance.  Otherwise, it specifies the minimum
    // BrowsingInstance ID, and the origin is isolated in all
    // BrowsingInstances with IDs greater than or equal to this value.
    BrowsingInstanceId browsing_instance_id_;

    // Optional information about the profile where the isolated origin
    // applies.  |browser_context_| may be used on the UI thread, and
    // |resource_context_| may be used on the IO thread.  If these are null,
    // then the isolated origin applies globally to all profiles.
    raw_ptr<BrowserContext> browser_context_;
    raw_ptr<ResourceContext> resource_context_;

    // True if origins at this or lower level should be treated as distinct
    // isolated origins, effectively isolating all domains below a given domain,
    // e.g. if the origin is https://foo.com and isolate_all_subdomains_ is
    // true, then https://bar.foo.com, https://qux.bar.foo.com and all
    // subdomains of the form https://<<any pattern here>>.foo.com are
    // considered isolated origins.
    bool isolate_all_subdomains_;

    // This tracks 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.
    IsolatedOriginSource source_;
  };

  // A struct to hold the OAC opted-in origins and their isolation state. It
  // associates a specific |origin| with its OriginAgentClusterIsolationState,
  // and is tracked in |origin_isolation_by_browsing_instance_|.
  struct OriginAgentClusterOptInEntry {
    OriginAgentClusterOptInEntry(
        const OriginAgentClusterIsolationState& oac_isolation_state_in,
        const url::Origin& origin_in);
    OriginAgentClusterOptInEntry(const OriginAgentClusterOptInEntry&);
    ~OriginAgentClusterOptInEntry();

    OriginAgentClusterIsolationState oac_isolation_state;
    url::Origin origin;
  };

  // Obtain an instance of ChildProcessSecurityPolicyImpl via GetInstance().
  ChildProcessSecurityPolicyImpl();
  friend struct base::DefaultSingletonTraits<ChildProcessSecurityPolicyImpl>;

  // Determines if certain permissions were granted for a file to given child
  // process. |permissions| is an internally defined bit-set.
  bool ChildProcessHasPermissionsForFile(int child_id,
                                         const base::FilePath& file,
                                         int permissions)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);

  // Grant a particular permission set for a file. |permissions| is an
  // internally defined bit-set.
  void GrantPermissionsForFile(int child_id,
                               const base::FilePath& file,
                               int permissions);

  // Grants access permission to the given isolated file system
  // identified by |filesystem_id|.  See comments for
  // ChildProcessSecurityPolicy::GrantReadFileSystem() for more details.
  void GrantPermissionsForFileSystem(int child_id,
                                     const std::string& filesystem_id,
                                     int permission);

  // Determines if certain permissions were granted for a file. |permissions|
  // is an internally defined bit-set.
  bool HasPermissionsForFile(int child_id,
                             const base::FilePath& file,
                             int permissions);

  // Determines if certain permissions were granted for a file in FileSystem
  // API. |permissions| is an internally defined bit-set.
  bool HasPermissionsForFileSystemFile(
      int child_id,
      const storage::FileSystemURL& filesystem_url,
      int permissions);

  // Determines if certain permissions were granted for a file system.
  // |permissions| is an internally defined bit-set.
  bool HasPermissionsForFileSystem(int child_id,
                                   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_);

  // Convert a list of comma separated isolated origins in |pattern_list|,
  // specified either as wildcard origins, non-wildcard origins or a mix of the
  // two into IsolatedOriginPatterns, suitable for addition via
  // AddFutureIsolatedOrigins().
  static std::vector<IsolatedOriginPattern> ParseIsolatedOrigins(
      std::string_view pattern_list);

  void AddFutureIsolatedOrigins(
      const std::vector<IsolatedOriginPattern>& patterns,
      IsolatedOriginSource source,
      BrowserContext* browser_context = nullptr);

  // Internal helper used for adding a particular isolated origin.  See
  // IsolatedOriginEntry for descriptions of various parameters.
  void AddIsolatedOriginInternal(BrowserContext* browser_context,
                                 const url::Origin& origin,
                                 bool applies_to_future_browsing_instances,
                                 BrowsingInstanceId browsing_instance_id,
                                 bool isolate_all_subdomains,
                                 IsolatedOriginSource source)
      EXCLUSIVE_LOCKS_REQUIRED(isolated_origins_lock_);

  bool AddProcessReference(int child_id, bool duplicating_handle);
  bool AddProcessReferenceLocked(int child_id, bool duplicating_handle)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);
  void RemoveProcessReference(int child_id);
  void RemoveProcessReferenceLocked(int child_id)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);

  // Internal helper for RemoveAllStateForBrowsingInstance().
  void RemoveAllStateForBrowsingInstanceInternal(
      const BrowsingInstanceId browsing_instance_id);

  // Creates the value to place in the "killed_process_origin_lock" crash key
  // based on the contents of |security_state|.
  static std::string GetKilledProcessOriginLock(
      const SecurityState* security_state);

  // Helper for CanAccessMaybeOpaqueOrigin, to perform two security checks:
  //  - Jail check: a process locked to a particular site shouldn't access data
  //    belonging to other sites.
  //  - Citadel check: a process not locked to any site shouldn't access data
  //    belonging to sites that require a dedicated process.
  //
  // These checks are performed by comparing the actual ProcessLock of the
  // process represented by `child_id` and `security_state` to an expected
  // ProcessLock computed from `url`, which takes into account factors such as
  // whether `url` should be site-isolated or origin-isolated (or not isolated,
  // e.g. on Android). Determining site-vs-origin isolation is non-trivial: the
  // answer may differ depending on BrowsingInstance (e.g., OriginAgentCluster
  // might require origin isolation only for certain BrowsingInstances), so all
  // BrowsingInstances hosting in the process must be consulted.
  //
  // This function returns true only if both Jail and Citadel checks pass. On
  // failure, it also populates `out_failure_reason` with debugging information
  // about the cause of the failure, as well as `out_expected_process_lock` with
  // what the process lock was expected to be (e.g., to be used in crash keys).
  //
  // This function must be called while already holding `lock_`.
  bool PerformJailAndCitadelChecks(int child_id,
                                   SecurityState* security_state,
                                   const GURL& url,
                                   bool url_is_precursor_of_opaque_origin,
                                   AccessType access_type,
                                   ProcessLock& out_expected_process_lock,
                                   std::string& out_failure_reason)
      EXCLUSIVE_LOCKS_REQUIRED(lock_);

  // Helper for public CanAccessOrigin overloads.
  bool CanAccessMaybeOpaqueOrigin(int child_id,
                                  const GURL& url,
                                  bool url_is_precursor_of_opaque_origin,
                                  AccessType access_type);

  // Helper used by CanAccessOrigin to impose additional restrictions on a
  // sandboxed process locked to `process_lock`.
  bool IsAccessAllowedForSandboxedProcess(const ProcessLock& process_lock,
                                          const GURL& url,
                                          bool url_is_for_opaque_origin,
                                          AccessType access_type);

  // Helper used by CanAccessOrigin to impose additional restrictions on a
  // process that only hosts PDF documents.
  bool IsAccessAllowedForPdfProcess(AccessType access_type);

  // Utility function to simplify lookups for OriginAgentClusterOptInEntry
  // values by origin.
  OriginAgentClusterIsolationState* LookupOriginIsolationState(
      const BrowsingInstanceId& browsing_instance_id,
      const url::Origin& origin)
      EXCLUSIVE_LOCKS_REQUIRED(origins_isolation_opt_in_lock_);

  // You must acquire this lock before reading or writing any members of this
  // class, except for isolated_origins_, schemes_okay_to_*, and
  // pseudo_schemes_, which use their own locks.  You must not block while
  // holding this lock.
  base::Lock lock_;

  // These schemes are allow-listed for all child processes in various contexts.
  // These sets are protected by |schemes_lock_| rather than |lock_|.
  base::Lock schemes_lock_;
  SchemeSet schemes_okay_to_commit_in_any_process_ GUARDED_BY(schemes_lock_);
  SchemeSet schemes_okay_to_request_in_any_process_ GUARDED_BY(schemes_lock_);
  SchemeSet schemes_okay_to_appear_as_origin_headers_ GUARDED_BY(schemes_lock_);

  // These schemes do not actually represent retrievable URLs.  For example,
  // the the URLs in the "about" scheme are aliases to other URLs.  This set is
  // protected by |schemes_lock_|.
  SchemeSet pseudo_schemes_ GUARDED_BY(schemes_lock_);

  // This map holds a SecurityState for each child process.  The key for the
  // map is the ID of the ChildProcessHost.  The SecurityState objects are
  // owned by this object and are protected by |lock_|.  References to them must
  // not escape this class.
  SecurityStateMap security_state_ 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_);

  // Contains a mapping between child process ID and the number of outstanding
  // references that want to keep the SecurityState for each process alive.
  // This object and Handles created by this object increment/decrement
  // the counts in this map and only destroy a SecurityState object for a
  // process when its count goes to zero.
  std::map<int, int> process_reference_counts_ 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 |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
  // https://www.bar.com would result in the following structure:
  //   https://foo.com -> { https://foo.com, https://bar.foo.com }
  //   https://bar.com -> { https://www.bar.com }
  // This organization speeds up lookups of isolated origins. The site can be
  // found in O(log n) time, and the corresponding list of origins to search
  // using the expensive DoesOriginMatchIsolatedOrigin() comparison is
  // typically small.
  //
  // Each origin entry stores information about:
  //   1. Which BrowsingInstances it applies to.  This is a combination of a
  //      BrowsingInstance ID |browsing_instance_id_| and a bool flag
  //      |applies_to_future_browsing_instances_| stored in in each origin's
  //      IsolatedOriginEntry.  When |applies_to_future_browsing_instances_| is
  //      true, the origin will be isolated in all BrowsingInstances with
  //      IDs equal to or greater than |browsing_instance_id_|. When
  //      |applies_to_future_browsing_instances_| is false, the origin will be
  //      isolated only in a single BrowsingInstance with ID
  //      |browsing_instance_id_|.
  //   2. Optionally, which BrowserContext (profile) it applies to.  When the
  //      |browser_context| field in the IsolatedOriginEntry is non-null, a
  //      particular isolated origin entry only applies to that BrowserContext.
  //      A ResourceContext, BrowserContext's representation on the IO thread,
  //      is also stored in the entry to facilitate checks on the IO thread.
  //      Note that the same origin may be isolated in different profiles,
  //      possibly with different BrowsingInstance ID cut-offs.  For example:
  //        https://foo.com -> { [https://test.foo.com profile1 4],
  //                             [https://test.foo.com profile2 7] }
  //      represents https://test.foo.com being isolated in profile1
  //      with BrowsingInstance ID 4, and also in profile2 with
  //      BrowsingInstance ID 7.
  base::flat_map<GURL, std::vector<IsolatedOriginEntry>> isolated_origins_
      GUARDED_BY(isolated_origins_lock_);

  // TODO(wjmaclean): Move these lists into a per-BrowserContext container, to
  // prevent any record of sites visible in one profile from being visible to
  // another profile.
  base::Lock origins_isolation_opt_in_lock_;
  // The set of all origins that have ever requested opt-in isolation or
  // requested to opt-out, organized by BrowserContext. This is tracked so we
  // know which origins need to be tracked when using default isolation in any
  // given BrowsingInstance. Origins requesting isolation opt-in or out, if
  // successful, are marked as isolated or not via
  // DetermineOriginAgentClusterIsolation's checking
  // |requested_isolation_state|. Each BrowserContext's state is tracked
  // separately so that timing attacks do not reveal whether an origin has been
  // visited in another (e.g., incognito) BrowserContext. In general, the state
  // of other BrowsingInstances is not observable outside such timing side
  // channels.
  base::flat_map<BrowserContext*, base::flat_set<url::Origin>>
      origin_isolation_opt_ins_and_outs_
          GUARDED_BY(origins_isolation_opt_in_lock_);

  // A map to track origins that have been isolated within a given
  // BrowsingInstance, or that have been loaded in a BrowsingInstance without
  // isolation, but that have requested isolation in at least one other
  // BrowsingInstance. Origins loaded without isolation are tracked to make sure
  // we don't try to isolate the origin in the associated BrowsingInstance at a
  // later time, in order to keep the isolation consistent over the lifetime of
  // the BrowsingInstance.
  //
  // Note that this map does not currently distinguish between a non-sandboxed
  // origin and a precursor of a sandboxed origin, even though that's not
  // technically necessary. See https://crbug.com/446157743 and
  // https://crbug.com/40910871.
  base::flat_map<BrowsingInstanceId, std::vector<OriginAgentClusterOptInEntry>>
      origin_isolation_by_browsing_instance_
          GUARDED_BY(origins_isolation_opt_in_lock_);

  base::Lock are_v8_optimizations_disabled_lock_;

  // A map of BrowsingInstances and process-lock-origins to v8-optimization
  // verdicts. The purpose of the map is to ensure that changes in the return
  // value of ContentBrowserClient::AreV8OptimizationsDisabledForSite() only
  // affect process reuse decisions for future BrowsingInstances.
  base::flat_map<BrowsingInstanceId, base::flat_map<url::Origin, bool>>
      are_v8_optimizations_disabled_map_
          GUARDED_BY(are_v8_optimizations_disabled_lock_);

  // When we are notified a BrowsingInstance has destructed, delay cleanup by
  // this amount to allow outstanding IO thread requests to complete. May be set
  // to different values in tests. Note: the value is chosen to be slightly
  // longer than the KeepAliveHandleFactory delay of 30 seconds, with the aim of
  // covering the maximum time needed by any IncrementKeepAliveRefCount callers.
  // TODO(wjmaclean): we know the IncrementKeepAliveRefCount API needs
  // improvement, and with it the BrowsingInstance cleanup here can also be
  // improved.
  base::TimeDelta browsing_instance_cleanup_delay_;
};

}  // namespace content

#endif  // CONTENT_BROWSER_CHILD_PROCESS_SECURITY_POLICY_IMPL_H_
