1# Linux `SUID` Sandbox
2
3*IMPORTANT NOTE: The Linux SUID sandbox is almost but not completely removed.
4See https://bugs.chromium.org/p/chromium/issues/detail?id=598454
5This page is mostly out-of-date.*
6
7With [r20110](https://crrev.com/20110), Chromium on Linux can now sandbox its
8renderers using a `SUID` helper binary. This is one of
9[our layer-1 sandboxing solutions](sandboxing.md).
10
11## `SUID` helper executable
12
13The `SUID` helper binary is called `chrome_sandbox` and you must build it
14separately from the main 'chrome' target. Chrome now just assumes it's next
15to the executable in the same directory. You can also control its path
16by CHROME_DEVEL_SANDBOX environment variable.
17
18In order for the sandbox to be used, the following conditions must be met:
19
20*   The sandbox binary must be executable by the Chromium process.
21*   It must be `SUID` and executable by other.
22
23If these conditions are met then the sandbox binary is used to launch the zygote
24process. Once the zygote has started, it asks a helper process to chroot it to a
25temp directory.
26
27## `CLONE_NEWPID` method
28
29The sandbox does three things to restrict the authority of a sandboxed process.
30The `SUID` helper is responsible for the first two:
31
32*   The `SUID` helper chroots the process. This takes away access to the
33    filesystem namespace.
34*   The `SUID` helper puts the process in a PID namespace using the
35    `CLONE_NEWPID` option to
36    [clone()](http://www.kernel.org/doc/man-pages/online/pages/man2/clone.2.html).
37    This stops the sandboxed process from being able to `ptrace()` or `kill()`
38    unsandboxed processes.
39
40In addition:
41
42*   The [Linux Zygote](zygote.md) startup code sets the process to be
43    _undumpable_ using
44    [prctl()](http://www.kernel.org/doc/man-pages/online/pages/man2/prctl.2.html).
45    This stops sandboxed processes from being able to `ptrace()` each other.
46    More specifically, it stops the sandboxed process from being `ptrace()`'d by
47    any other process. This can be switched off with the
48    `--allow-sandbox-debugging` option.
49
50Limitations:
51
52*   Not all kernel versions support `CLONE_NEWPID`. If the `SUID` helper is run
53    on a kernel that does not support `CLONE_NEWPID`, it will ignore the problem
54    without a warning, but the protection offered by the sandbox will be
55    substantially reduced. See LinuxPidNamespaceSupport for how to test whether
56    your system supports PID namespaces.
57*   This does not restrict network access.
58*   This does not prevent processes within a given sandbox from sending each
59    other signals or killing each other.
60*   Setting a process to be undumpable is not irreversible. A sandboxed process
61    can make itself dumpable again, opening itself up to being taken over by
62    another process (either unsandboxed or within the same sandbox).
63    *   Breakpad (the crash reporting tool) makes use of this. If a process
64        crashes, Breakpad makes it dumpable in order to use ptrace() to halt
65        threads and capture the process's state at the time of the crash. This
66        opens a small window of vulnerability.
67
68## `setuid()` method
69
70_This is an alternative to the `CLONE_NEWPID` method; it is not currently
71implemented in the Chromium codebase._
72
73Instead of using `CLONE_NEWPID`, the `SUID` helper can use `setuid()` to put the
74process into a currently-unused UID, which is allocated out of a range of UIDs.
75In order to ensure that the `UID` has not been allocated for another sandbox,
76the `SUID` helper uses
77[getrlimit()](http://www.kernel.org/doc/man-pages/online/pages/man2/getrlimit.2.html)
78to set `RLIMIT_NPROC` temporarily to a soft limit of 1. (Note that the docs
79specify that [setuid()](http://www.kernel.org/doc/man-pages/online/pages/man2/setuid.2.html)
80returns `EAGAIN` if `RLIMIT_NPROC` is exceeded.)  We can reset `RLIMIT_NPROC`
81afterwards in order to allow the sandboxed process to fork child processes.
82
83As before, the `SUID` helper chroots the process.
84
85As before, LinuxZygote can set itself to be undumpable to stop processes in the
86sandbox from being able to `ptrace()` each other.
87
88Limitations:
89
90*   It is not possible for an unsandboxed process to `ptrace()` a sandboxed
91    process because they run under different UIDs. This makes debugging harder.
92    There is no equivalent of the `--allow-sandbox-debugging` other than turning
93    the sandbox off with `--no-sandbox`.
94*   The `SUID` helper can check that a `UID` is unused before it uses it (hence
95    this is safe if the `SUID` helper is installed into multiple chroots), but
96    it cannot prevent other root processes from putting processes into this
97    `UID` after the sandbox has been started. This means we should make the
98    `UID` range configurable, or distributions should reserve a `UID` range.
99
100## `CLONE_NEWNET` method
101
102The `SUID` helper uses
103[CLONE_NEWNET](http://www.kernel.org/doc/man-pages/online/pages/man2/clone.2.html)
104to restrict network access.
105
106## Future work
107
108We are splitting the `SUID` sandbox into a separate project which will support
109both the `CLONE_NEWNS` and `setuid()` methods:
110http://code.google.com/p/setuid-sandbox/
111
112Having the `SUID` helper as a separate project should make it easier for
113distributions to review and package.
114
115## Possible extensions
116
117## History
118
119Older versions of the sandbox helper process will _only_ run
120`/opt/google/chrome/chrome`. This string is hard coded
121(`sandbox/linux/suid/sandbox.cc`). If your package is going to place the
122Chromium binary somewhere else you need to modify this string.
123
124## See also
125
126*   [LinuxSUIDSandboxDevelopment](suid_sandbox_development.md)
127*   [LinuxSandboxing](sandboxing.md)
128*   General information on Chromium sandboxing:
129    https://dev.chromium.org/developers/design-documents/sandbox
130