Nested Content Processes

From MozillaWiki
Jump to navigation Jump to search

B2G is multi-process, but the hierarchy of processes is depth two: Only the root process can have child processes.

This creates a problem for us on B2G with the browser app. We'd like the browser app to run outside the root process, but we'd also like the browser app's tabs to run outside the browser app process (so that when a tab crashes e.g. due to OOM, it doesn't take down the whole browser). Right now we have to compromise. We can either run the browser app in the root process and run the browser tabs in their own processes, or we can run the browser app outside the root process and run the browser tabs inside the same process as the browser app. We chose the former.

One way this fix this is we could allow child processes to have their own children. But this would be a lot of work. One problem is that because an arbitrary-depth hierarchy of processes doesn't exist right now, I expect that most of our APIs won't work properly if we have nested content processes. Many of them explicitly don't even try to work correctly under these circumstances. We'd have to fix up all of these APIs and then get the graphics stack to work with nested content processes.

There is an alternative and perhaps simpler way of accomplishing our goal of moving the browser app out of the main process. It turns out that a child-of-a-child doesn't need to talk to its parent very often. Most of what it needs (e.g. network access, permission checks, hardware access) comes from the main process. So we could made our browser tab inside the browser process a child of the main process. We'd then fix up the few cases when the process wants to talk to its now-sibling.

This page describes how nested content processes is implemented.

Terminology

  1. Chrome Process, Root Process or B2G Process: The process with highest privilege which can access virtually all resources on the device. Many security and privacy sensitive API could only be performed by the chrome process. Content processes have to delegate the action to the chrome process through IPC.
  2. Content Process or Child Process: Processes with lower privilege. Almost all web apps and browser tabs run in this kind of process thus the name content process.
  3. Grand Child Process: The content processes whose parents are logically other content processes. In the OS's point of view, every content processes are still siblings.
  4. IPC Protocol: The protocol defines IPC messages sent between two threads or two processes. In code, a protocol class is usually named P<something>, see also IPC Protocols.
  5. Bridge: Toplevel protocol usually connects the chrome process with content processes. A bridge protocol connects two content processes.

Implementation

Process Creation

Nested Process

PBrowser are now managed by either PContent or PContentBridge so TabParents could be created in content process now.

Here is the steps for setting up nested OOP frame:

  1. Child process A ask chrome process to create a grand child process via PContent::CreateChildProcess()
  2. Child process A ask chrome process to bridge to grand child process B via PContent::BridgeToChildProcess()
  3. Child process A creates new PBrowser over PContentBridge::PBrowser

Security

[Needs security review]

Process based sandbox

The sandbox model is built on the process boundary. Generally the chrome process shouldn't trust the information coming from a content processes. The content processes also shouldn't trust the information coming from other content processes.

How do we check the integrity? For the messages from child to chrome we could

  1. Check if the process is the app as it claimed to be by comparing ContentParent::OwnOrContainingAppId() bug 1020157
  2. Check if the is indeed created and managed by the PContentBridge. When the content process creates a new TabParent/TabChild pair between it and the grand content process, it should send a notification to the chrome process. The chrome process will note that and check if the PBrowserId is indeed owned by the content process bug 1020172

How to check nested TabParent?

When a content process wants to create a new Tab, it should first ask the chrome process to allocate a PBrowserId and passing the TabContext to chrome. Chrome process then checks if the process could create the new Tab with the TabContext. If the check passed then the chrome process will allocate a new PBrowerId and record the (PBrowserId, TabContext) pair in the ContentParent. Next time when the TabChild wants to use some privileged API via ContentChild, the chrome process can check if the (PBrowserId, TabContext) matched the internal record. If not, then the child process will be killed.

framless

Testing

TBD