blob: 58456628b5f74b84c03f3b1b84797af556d5c3b7 [file] [log] [blame] [view]
andybonsad92aa32015-08-31 02:27:441# Linux `SUID` Sandbox
andybons3322f762015-08-24 21:37:092
andybonsad92aa32015-08-31 02:27:443With [r20110](https://crrev.com/20110), Chromium on Linux can now sandbox its
4renderers using a `SUID` helper binary. This is one of
5[our layer-1 sandboxing solutions](linux_sandboxing.md).
andybons3322f762015-08-24 21:37:096
andybonsad92aa32015-08-31 02:27:447## `SUID` helper executable
8
9The `SUID` helper binary is called `chrome_sandbox` and you must build it
10separately from the main 'chrome' target. To use this sandbox, you have to
11specify its path in the `linux_sandbox_path` GYP variable. When spawning the
12[zygote process](linux_zygote/md), if the `SUID` sandbox is enabled, Chromium
13will check for the sandbox binary at the location specified by
14`linux_sandbox_path`. For Google Chrome, this is set to
15`/opt/google/chrome/chrome-sandbox`, and early version had this value hard coded
16in `chrome/browser/zygote_host_linux.cc`.
andybons3322f762015-08-24 21:37:0917
18
19In order for the sandbox to be used, the following conditions must be met:
andybons3322f762015-08-24 21:37:0920
andybonsad92aa32015-08-31 02:27:4421* The sandbox binary must be executable by the Chromium process.
22* It must be `SUID` and executable by other.
andybons3322f762015-08-24 21:37:0923
andybonsad92aa32015-08-31 02:27:4424If these conditions are met then the sandbox binary is used to launch the zygote
25process. Once the zygote has started, it asks a helper process to chroot it to a
26temp directory.
andybons3322f762015-08-24 21:37:0927
andybonsad92aa32015-08-31 02:27:4428## `CLONE_NEWPID` method
29
30The sandbox does three things to restrict the authority of a sandboxed process.
31The `SUID` helper is responsible for the first two:
32
33* The `SUID` helper chroots the process. This takes away access to the
34 filesystem namespace.
35* The `SUID` helper puts the process in a PID namespace using the
36 `CLONE_NEWPID` option to
37 [clone()](http://www.kernel.org/doc/man-pages/online/pages/man2/clone.2.html).
38 This stops the sandboxed process from being able to `ptrace()` or `kill()`
39 unsandboxed processes.
andybons3322f762015-08-24 21:37:0940
41In addition:
andybonsad92aa32015-08-31 02:27:4442
43* The [Linux Zygote](linux_zygote.md) startup code sets the process to be
44 _undumpable_ using
45 [prctl()](http://www.kernel.org/doc/man-pages/online/pages/man2/prctl.2.html).
46 This stops sandboxed processes from being able to `ptrace()` each other.
47 More specifically, it stops the sandboxed process from being `ptrace()`'d by
48 any other process. This can be switched off with the
49 `--allow-sandbox-debugging` option.
andybons3322f762015-08-24 21:37:0950
51Limitations:
andybons3322f762015-08-24 21:37:0952
andybonsad92aa32015-08-31 02:27:4453* Not all kernel versions support `CLONE_NEWPID`. If the `SUID` helper is run
54 on a kernel that does not support `CLONE_NEWPID`, it will ignore the problem
55 without a warning, but the protection offered by the sandbox will be
56 substantially reduced. See LinuxPidNamespaceSupport for how to test whether
57 your system supports PID namespaces.
58* This does not restrict network access.
59* This does not prevent processes within a given sandbox from sending each
60 other signals or killing each other.
61* Setting a process to be undumpable is not irreversible. A sandboxed process
62 can make itself dumpable again, opening itself up to being taken over by
63 another process (either unsandboxed or within the same sandbox).
64 * Breakpad (the crash reporting tool) makes use of this. If a process
65 crashes, Breakpad makes it dumpable in order to use ptrace() to halt
66 threads and capture the process's state at the time of the crash. This
67 opens a small window of vulnerability.
andybons3322f762015-08-24 21:37:0968
andybonsad92aa32015-08-31 02:27:4469## `setuid()` method
andybons3322f762015-08-24 21:37:0970
andybonsad92aa32015-08-31 02:27:4471_This is an alternative to the `CLONE_NEWPID` method; it is not currently
72implemented in the Chromium codebase._
andybons3322f762015-08-24 21:37:0973
andybonsad92aa32015-08-31 02:27:4474Instead of using `CLONE_NEWPID`, the `SUID` helper can use `setuid()` to put the
75process into a currently-unused UID, which is allocated out of a range of UIDs.
76In order to ensure that the `UID` has not been allocated for another sandbox,
77the `SUID` helper uses
78[getrlimit()](http://www.kernel.org/doc/man-pages/online/pages/man2/getrlimit.2.html)
79to set `RLIMIT_NPROC` temporarily to a soft limit of 1. (Note that the docs
80specify that [setuid()](http://www.kernel.org/doc/man-pages/online/pages/man2/setuid.2.html)
81returns `EAGAIN` if `RLIMIT_NPROC` is exceeded.) We can reset `RLIMIT_NPROC`
82afterwards in order to allow the sandboxed process to fork child processes.
andybons3322f762015-08-24 21:37:0983
andybonsad92aa32015-08-31 02:27:4484As before, the `SUID` helper chroots the process.
85
86As before, LinuxZygote can set itself to be undumpable to stop processes in the
87sandbox from being able to `ptrace()` each other.
andybons3322f762015-08-24 21:37:0988
89Limitations:
andybons3322f762015-08-24 21:37:0990
andybonsad92aa32015-08-31 02:27:4491* It is not possible for an unsandboxed process to `ptrace()` a sandboxed
92 process because they run under different UIDs. This makes debugging harder.
93 There is no equivalent of the `--allow-sandbox-debugging` other than turning
94 the sandbox off with `--no-sandbox`.
95* The `SUID` helper can check that a `UID` is unused before it uses it (hence
96 this is safe if the `SUID` helper is installed into multiple chroots), but
97 it cannot prevent other root processes from putting processes into this
98 `UID` after the sandbox has been started. This means we should make the
99 `UID` range configurable, or distributions should reserve a `UID` range.
andybons3322f762015-08-24 21:37:09100
andybonsad92aa32015-08-31 02:27:44101## `CLONE_NEWNET` method
102
103The `SUID` helper uses
104[CLONE_NEWNET](http://www.kernel.org/doc/man-pages/online/pages/man2/clone.2.html)
105to restrict network access.
andybons3322f762015-08-24 21:37:09106
107## Future work
108
andybonsad92aa32015-08-31 02:27:44109We are splitting the `SUID` sandbox into a separate project which will support
110both the `CLONE_NEWNS` and `setuid()` methods:
111http://code.google.com/p/setuid-sandbox/
andybons3322f762015-08-24 21:37:09112
andybonsad92aa32015-08-31 02:27:44113Having the `SUID` helper as a separate project should make it easier for
114distributions to review and package.
andybons3322f762015-08-24 21:37:09115
116## Possible extensions
117
118## History
119
andybonsad92aa32015-08-31 02:27:44120Older versions of the sandbox helper process will _only_ run
121`/opt/google/chrome/chrome`. This string is hard coded
122(`sandbox/linux/suid/sandbox.cc`). If your package is going to place the
123Chromium binary somewhere else you need to modify this string.
andybons3322f762015-08-24 21:37:09124
125## See also
andybonsad92aa32015-08-31 02:27:44126
127* [LinuxSUIDSandboxDevelopment](linux_suid_sandbox_development.md)
128* [LinuxSandboxing](linux_sandboxing.md)
129* General information on Chromium sandboxing:
130 http://dev.chromium.org/developers/design-documents/sandbox