andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 1 | # Linux Sandbox IPC |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 2 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 3 | The Sandbox IPC system is separate from the 'main' IPC system. The sandbox IPC |
| 4 | is a lower level system which deals with cases where we need to route requests |
| 5 | from the bottom of the call stack up into the browser. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 6 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 7 | The motivating example is Skia, which uses fontconfig to load fonts. In a |
| 8 | chrooted renderer we cannot access the user's fontcache, nor the font files |
| 9 | themselves. However, font loading happens when we have called through WebKit, |
| 10 | through Skia and into the SkFontHost. At this point, we cannot loop back around |
| 11 | to use the main IPC system. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 12 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 13 | Thus we define a small IPC system which doesn't depend on anything but `base` |
| 14 | and which can make synchronous requests to the browser process. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 15 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 16 | The [zygote](linux_zygote.md) starts with a `UNIX DGRAM` socket installed in a |
| 17 | well known file descriptor slot (currently 4). Requests can be written to this |
| 18 | socket which are then processed on a special "sandbox IPC" process. Requests |
| 19 | have a magic `int` at the beginning giving the type of the request. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 20 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 21 | All renderers share the same socket, so replies are delivered via a reply |
| 22 | channel which is passed as part of the request. So the flow looks like: |
| 23 | |
| 24 | 1. The renderer creates a `UNIX DGRAM` socketpair. |
| 25 | 1. The renderer writes a request to file descriptor 4 with an `SCM_RIGHTS` |
| 26 | control message containing one end of the fresh socket pair. |
| 27 | 1. The renderer blocks reading from the other end of the fresh socketpair. |
| 28 | 1. A special "sandbox IPC" process receives the request, processes it and |
| 29 | writes the reply to the end of the socketpair contained in the request. |
| 30 | 1. The renderer wakes up and continues. |
| 31 | |
| 32 | The browser side of the processing occurs in |
| 33 | `chrome/browser/renderer_host/render_sandbox_host_linux.cc`. The renderer ends |
| 34 | could occur anywhere, but the browser side has to know about all the possible |
| 35 | requests so that should be a good starting point. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 36 | |
| 37 | Here is a (possibly incomplete) list of endpoints in the renderer: |
| 38 | |
| 39 | ### fontconfig |
| 40 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 41 | As mentioned above, the motivating example of this is dealing with fontconfig |
| 42 | from a chrooted renderer. We implement our own Skia FontHost, outside of the |
| 43 | Skia tree, in `skia/ext/SkFontHost_fontconfig**`. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 44 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 45 | There are two methods used. One for performing a match against the fontconfig |
| 46 | data and one to return a file descriptor to a font file resulting from one of |
| 47 | those matches. The only wrinkle is that fontconfig is a single-threaded library |
| 48 | and it's already used in the browser by GTK itself. |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 49 | |
| 50 | Thus, we have a couple of options: |
andybons | 3322f76 | 2015-08-24 21:37:09 | [diff] [blame] | 51 | |
andybons | ad92aa3 | 2015-08-31 02:27:44 | [diff] [blame] | 52 | 1. Handle the requests on the UI thread in the browser. |
| 53 | 1. Handle the requests in a separate address space. |
| 54 | |
| 55 | The original implementation did the former (handle on UI thread). This turned |
| 56 | out to be a terrible idea, performance wise, so we now handle the requests on a |
| 57 | dedicated process. |