- Linux Sandboxing
- Layered approach
- Sandbox types summary
- The setuid sandbox
- User namespaces sandbox
- The seccomp-bpf sandbox
- The seccomp sandbox
- SELinux
- Developing and debugging with sandboxing
- See also
- Linux SUID Sandbox Development
- Installation instructions for developers
- Try bots and waterfall
- Disabling the sandbox
- Installation instructions for “Raw builds of Chromium”
- System-wide installations of Chromium
- Chromium: «Running without the SUID sandbox!» error
- 5 Answers 5
Linux Sandboxing
Chromium uses a multiprocess model, which allows to give different privileges and restrictions to different parts of the browser. For instance, we want renderers to run with a limited set of privileges since they process untrusted input and are likely to be compromised. Renderers will use an IPC mechanism to request access to resource from a more privileged (browser process). You can find more about this general design here.
We use different sandboxing techniques on Linux and Chrome OS, in combination, to achieve a good level of sandboxing. You can see which sandboxes are currently engaged by looking at chrome://sandbox (renderer processes) and chrome://gpu (gpu process).
We have a two layers approach:
- Layer-1 (also called the “semantics” layer) prevents access to most resources from a process where it’s engaged. The setuid sandbox is used for this.
- Layer-2 (also called “attack surface reduction” layer) restricts access from a process to the attack surface of the kernel. Seccomp-BPF is used for this.
You can disable all sandboxing (for testing) with —no-sandbox .
Layered approach
One notable difficulty with seccomp-bpf is that filtering at the system call interface provides difficult to understand semantics. One crucial aspect is that if a process A runs under seccomp-bpf , we need to guarantee that it cannot affect the integrity of process B running under a different seccomp-bpf policy (which would be a sandbox escape). Besides the obvious system calls such as ptrace() or process_vm_writev() , there are multiple subtle issues, such as using open() on /proc entries.
Our layer-1 guarantees the integrity of processes running under different seccomp-bpf policies. In addition, it allows restricting access to the network, something that is difficult to perform at the layer-2.
Sandbox types summary
Name | Layer and process | Linux flavors where available | State |
---|---|---|---|
Setuid sandbox | Layer-1 in Zygote processes (renderers, PPAPI, NaCl, some utility processes) | Linux distributions and Chrome OS | Enabled by default (old kernels) and maintained |
User namespaces sandbox | Modern alternative to the setuid sandbox. Layer-1 in Zygote processes (renderers, PPAPI, NaCl, some utility processes) | Linux distributions and Chrome OS (kernel >= 3.8) | Enabled by default (modern kernels) and actively developed |
Seccomp-BPF | Layer-2 in some Zygote processes (renderers, PPAPI, NaCl), Layer-1 + Layer-2 in GPU process | Linux kernel >= 3.5, Chrome OS and Ubuntu | Enabled by default and actively developed |
Seccomp-legacy | Layer-2 in renderers | All | Deprecated |
SELinux | Layer-1 in Zygote processes (renderers, PPAPI) | SELinux distributions | Deprecated |
AppArmor | Outer layer-1 in Zygote processes (renderers, PPAPI) | Not used | Deprecated |
The setuid sandbox
Also called SUID sandbox, our main layer-1 sandbox.
A SUID binary that will create a new network and PID namespace, as well as chroot() the process to an empty directory on request.
To disable it, use —disable-setuid-sandbox . (Do not remove the binary or unset CHROME_DEVEL_SANDBOX , it is not supported).
User namespaces sandbox
The namespace sandbox aims to replace the setuid sandbox. It has the advantage of not requiring a setuid binary. It’s based on (unprivileged) user namespaces in the Linux kernel. It generally requires a kernel >= 3.10, although it may work with 3.8 if certain patches are backported.
Starting with M-43, if the kernel supports it, unprivileged namespaces are used instead of the setuid sandbox. Starting with M-44, certain processes run in their own PID namespace, which isolates them better.
The seccomp-bpf sandbox
Also called seccomp-filters sandbox.
Our main layer-2 sandbox, designed to shelter the kernel from malicious code executing in userland.
Also used as layer-1 in the GPU process. A BPF compiler will compile a process-specific program to filter system calls and send it to the kernel. The kernel will interpret this program for each system call and allow or disallow the call.
To help with sandboxing of existing code, the kernel can also synchronously raise a SIGSYS signal. This allows user-land to perform actions such as “log and return errno”, emulate the system call or broker-out the system call (perform a remote system call via IPC). Implementing this requires a low-level async-signal safe IPC facility.
seccomp-bpf is supported since Linux 3.5, but is also back-ported on Ubuntu 12.04 and is always available on Chrome OS. See this page for more information.
See this blog post announcing Chrome support. Or this one for a more technical overview.
This sandbox can be disabled with —disable-seccomp-filter-sandbox .
The seccomp sandbox
Also called seccomp-legacy . An obsolete layer-1 sandbox, then available as an optional layer-2 sandbox.
Deprecated by seccomp-bpf and removed from the Chromium code base. It still exists as a separate project here.
SELinux
Deprecated. Was designed to be used instead of the SUID sandbox.
Old information for archival purposes:
One can build Chromium with selinux=1 and the Zygote (which starts the renderers and PPAPI processes) will do a dynamic transition. audit2allow will quickly build a usable module.
Available since r26257, more information in this blog post (grep for ‘dynamic’ since dynamic transitions are a little obscure in SELinux)
Developing and debugging with sandboxing
Sandboxing can make developing harder, see:
See also
Linux SUID Sandbox Development
We need a SUID helper binary to turn on the sandbox on Linux.
In most cases, you can run build/update-linux-sandbox.sh and it’ll install the proper sandbox for you in /usr/local/sbin and tell you to update your .bashrc if needed.
Installation instructions for developers
Running without the SUID sandbox!
The setuid sandbox provides API version X, but you need Y You are using a wrong version of the setuid binary!
Run the script mentioned above, or do something such as:
- Build chrome_sandbox whenever you build chrome ( ninja -C xxx chrome chrome_sandbox instead of ninja -C xxx chrome )
- After building, run something similar to (or use the provided update-linux-sandbox.sh ):
# needed if you build on NFS! sudo cp out/Debug/chrome_sandbox /usr/local/sbin/chrome-devel-sandbox sudo chown root:root /usr/local/sbin/chrome-devel-sandbox sudo chmod 4755 /usr/local/sbin/chrome-devel-sandbox
export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox
Try bots and waterfall
If you’re installing a new bot, always install the setuid sandbox (the instructions are different than for developers, contact the Chrome troopers). If something does need to run without the setuid sandbox, use the —disable-setuid-sandbox command line flag.
The SUID sandbox must be enabled on the try bots and the waterfall. If you don’t use it locally, things might appear to work for you, but break on the bots.
(Note: as a temporary, stop gap measure, setting CHROME_DEVEL_SANDBOX to an empty string is equivalent to —disable-setuid-sandbox )
Disabling the sandbox
If you are certain that you don‘t want the setuid sandbox, use —disable-setuid-sandbox . There should be very few cases like this. So if you’re not absolutely sure, run with the setuid sandbox.
Installation instructions for “Raw builds of Chromium”
If you’re using a “raw” build of Chromium, do the following:
sudo chown root:root chrome_sandbox && sudo chmod 4755 chrome_sandbox && \ export CHROME_DEVEL_SANDBOX="$PWD/chrome_sandbox" ./chrome
You can also make such an installation more permanent by following the steps above and installing chrome_sandbox to a more permanent location.
System-wide installations of Chromium
The CHROME_DEVEL_SANDBOX variable is intended for developers and won’t work for a system-wide installation of Chromium. Package maintainers should make sure the setuid binary is installed.
Chromium: «Running without the SUID sandbox!» error
I’ve downloaded and unpacked a fresh copy of Chromium (Linux_x64), and when I try to run the chrome binary, this happens:
[23986:23986:0806/143027:FATAL:browser_main_loop.cc(148)] Running without the SUID sandbox! See https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for more information on developing with the sandbox on. Aborted (core dumped)
It doesn’t happen with Ubuntu’s chromium-browser package. I can bypass the error by running Chromium with —no-sandbox but I’d rather leave the sandbox enabled. chrome_sandbox has permissions 4755 and is executable by chrome . Does anyone know how to fix this error? It might not be related, but I’m using full-disk encryption on my Ubuntu install.
5 Answers 5
Download chrome-linux.zip from appropriate folder from here.
Extract the file — will get a folder called chrome-linux .
Move the folder to wherever you want — I move it to my home folder.
Previous two step might be reversed.
Run these four commands individually:
sudo mv chrome_sandbox chrome-sandbox sudo chown root chrome-sandbox sudo chmod 4755 chrome-sandbox ./chrome-wrapper
When I do that, I am good to go.
$ export DISPLAY=:0.0 && ./chrome --no-sandbox
Development of chrome sandbox stopped early 2016 (latest version of chrome-linux (64bit) that Lyle mentioned is http://commondatastorage.googleapis.com/chromium-browser-continuous/index.html?prefix=Linux_x64/382014/ which is from March 2016, more than a year ago).
That discussion seems to indicate that with the appropriate kernel support it is safe to run chrome with —disable-setuid-sandbox which should cause chrome to stop even looking for the sandbox, but refuse to run if your kernel hasn’t got the support to safely do so.
Nevertheless, at this moment (April 2017) ubuntu Stable (Xenial) still comes with the sandbox; package chromium-browser contains: /usr/lib/chromium-browser/chrome-sandbox which is setuid root. The reason that I did got the error in the title of this question is that I was running a special version of chrome that was part of a package that came with an application (a SecondLife viewer) that found it necessary to provide their own version of the browser. Needless to say that this downloaded package wasn’t installed with setuid root :p (nor would I suggest to change it to 4755, because that doesn’t sound very secure to do).