process_map.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef EXTENSIONS_BROWSER_PROCESS_MAP_H_
  5. #define EXTENSIONS_BROWSER_PROCESS_MAP_H_
  6. #include <stddef.h>
  7. #include <set>
  8. #include <string>
  9. #include "components/keyed_service/core/keyed_service.h"
  10. #include "content/public/browser/site_instance.h"
  11. #include "extensions/common/features/feature.h"
  12. namespace content {
  13. class BrowserContext;
  14. }
  15. namespace extensions {
  16. class Extension;
  17. // Contains information about which extensions are assigned to which processes.
  18. //
  19. // The relationship between extensions and processes is complex:
  20. //
  21. // - Extensions can be either "split" mode or "spanning" mode.
  22. // - In spanning mode, extensions *generally* share a single process between all
  23. // incognito and normal windows. This was the original mode for extensions.
  24. // - In split mode, extensions have separate processes in incognito windows.
  25. // - There are also hosted apps, which are a kind of extensions, and those
  26. // usually have a process model similar to normal web sites: multiple
  27. // processes per-profile.
  28. // - A single hosted app can have more than one SiteInstance in the same process
  29. // if we're over the process limit and force them to share a process.
  30. // - An extension can also opt into Cross Origin Isolation in which case it can
  31. // have multiple processes per profile since cross-origin-isolated and
  32. // non-cross-origin-isolated contexts don't share a process.
  33. //
  34. // In general, we seem to play with the process model of extensions a lot, so
  35. // it is safest to assume it is many-to-many in most places in the codebase.
  36. //
  37. // Note that because of content scripts, frames, and other edge cases in
  38. // Chrome's process isolation, extension code can still end up running outside
  39. // an assigned process.
  40. //
  41. // But we only allow high-privilege operations to be performed by an extension
  42. // when it is running in an assigned process.
  43. //
  44. // ===========================================================================
  45. // WARNINGS - PLEASE UNDERSTAND THESE BEFORE CALLING OR MODIFYING THIS CLASS
  46. // ===========================================================================
  47. //
  48. // 1. This class contains the processes for hosted apps as well as extensions
  49. // and packaged apps. Just because a process is present here *does not* mean
  50. // it is an "extension process" (e.g., for UI purposes). It may contain only
  51. // hosted apps. See crbug.com/102533.
  52. //
  53. // 2. An extension can show up in multiple processes. That is why there is no
  54. // GetExtensionProcess() method here. There are multiple such cases:
  55. // a) The extension is actually a hosted app.
  56. // b) There is an incognito window open and the extension is "split mode".
  57. // c) The extension is cross origin isolated but has
  58. // non-cross-origin-isolated contexts.
  59. // It is *not safe* to assume that there is one process per extension.
  60. //
  61. // 3. The process ids contained in this class are *not limited* to the Profile
  62. // you got this map from. They can also be associated with that profile's
  63. // incognito/normal twin. If you care about this, use
  64. // RenderProcessHost::FromID() and check the profile of the resulting object.
  65. //
  66. // TODO(aa): The above warnings suggest this class could use improvement :).
  67. //
  68. // TODO(kalman): This class is not threadsafe, but is used on both the UI and IO
  69. // threads. Somebody should fix that, either make it threadsafe or
  70. // enforce single thread. Investigation required.
  71. class ProcessMap : public KeyedService {
  72. public:
  73. ProcessMap();
  74. ProcessMap(const ProcessMap&) = delete;
  75. ProcessMap& operator=(const ProcessMap&) = delete;
  76. ~ProcessMap() override;
  77. // Returns the instance for |browser_context|. An instance is shared between
  78. // an incognito and a regular context.
  79. static ProcessMap* Get(content::BrowserContext* browser_context);
  80. size_t size() const { return items_.size(); }
  81. bool Insert(const std::string& extension_id,
  82. int process_id,
  83. content::SiteInstanceId site_instance_id);
  84. bool Remove(const std::string& extension_id,
  85. int process_id,
  86. content::SiteInstanceId site_instance_id);
  87. int RemoveAllFromProcess(int process_id);
  88. bool Contains(const std::string& extension_id, int process_id) const;
  89. bool Contains(int process_id) const;
  90. std::set<std::string> GetExtensionsInProcess(int process_id) const;
  91. // Gets the most likely context type for the process with ID |process_id|
  92. // which hosts Extension |extension|, if any (may be nullptr). Context types
  93. // are renderer (JavaScript) concepts but the browser can do a decent job in
  94. // guessing what the process hosts.
  95. //
  96. // For Context types with no |extension| e.g. untrusted WebUIs, we use |url|
  97. // which should correspond to the URL where the API is running.|url| could be
  98. // the frame's URL, the Content Script's URL, or the URL where a Content
  99. // Script is running. So |url| should only be used when there is no
  100. // |extension|. |url| may be also be nullptr when running in Service Workers.
  101. // Currently, the |url| provided by event_router.cc is passed from the
  102. // renderer process and therefore can't be fully trusted.
  103. // TODO(ortuno): Change call sites to only pass in a URL when |extension| is
  104. // nullptr and only use a URL retrieved from the browser process.
  105. //
  106. // |extension| is the funky part - unfortunately we need to trust the
  107. // caller of this method to be correct that indeed the context does feature
  108. // an extension. This matters for iframes, where an extension could be
  109. // hosted in another extension's process (privilege level needs to be
  110. // downgraded) or in a web page's process (privilege level needs to be
  111. // upgraded).
  112. //
  113. // The latter of these is slightly problematic from a security perspective;
  114. // if a web page renderer gets owned it could try to pretend it's an
  115. // extension and get access to some unprivileged APIs. Luckly, when OOP
  116. // iframes lauch, it won't be an issue.
  117. //
  118. // Anyhow, the expected behaviour is:
  119. // - For hosted app processes, this will be blessed_web_page.
  120. // - For processes of platform apps running on lock screen, this will be
  121. // lock_screen_extension.
  122. // - For other extension processes, this will be blessed_extension.
  123. // - For WebUI processes, this will be a webui.
  124. // - For chrome-untrusted:// URLs, this will be a webui_untrusted_context.
  125. // - For any other extension we have the choice of unblessed_extension or
  126. // content_script. Since content scripts are more common, guess that.
  127. // We *could* in theory track which web processes have extension frames
  128. // in them, and those would be unblessed_extension, but we don't at the
  129. // moment, and once OOP iframes exist then there won't even be such a
  130. // thing as an unblessed_extension context.
  131. // - For anything else, web_page.
  132. Feature::Context GetMostLikelyContextType(const Extension* extension,
  133. int process_id,
  134. const GURL* url) const;
  135. void set_is_lock_screen_context(bool is_lock_screen_context) {
  136. is_lock_screen_context_ = is_lock_screen_context;
  137. }
  138. private:
  139. struct Item;
  140. typedef std::set<Item> ItemSet;
  141. ItemSet items_;
  142. // Whether the process map belongs to the browser context used on Chrome OS
  143. // lock screen.
  144. bool is_lock_screen_context_ = false;
  145. };
  146. } // namespace extensions
  147. #endif // EXTENSIONS_BROWSER_PROCESS_MAP_H_