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