Note: The documentation for Chrome’s Linux sandbox is lacking. This is my attempt to make sense of it and clarify how it works for users who may not want to sift through multiple docs on the subject. If I have misinterpreted, let me know, some of the docs are out of date and I may not have been informed.
Chrome is well known for its sandbox, which has held up incredibly well over the years – not a single in the wild attack against it. But on the Linux side of things it’s even more impressive, Chrome’s sandbox is immensely more powerful than on Windows. Though the architecture is similar, the mechanism is fairly different.
Chrome’s architecture is made up of multiple parts – on Linux there is a broker, your SetUID Sandbox process, and your tabs, renderer, plugins, and extensions (the Zygote processes).
The Chrome-Sandbox SUID Helper Binary launches when Chrome does, and sets up the sandbox environment. The sandbox environment is meant to be restrictive to the file system and other processes, attempting to isolate various Chrome parts (such as the renderer) from the system.
A sandboxed process is put inside a Chroot, a sort of a virtual file system (chroot = change root, it’s a new root). It basically gets its own file system to work with, an din this case, it’s not given any write access to the system. The limitations imposed on the process prevent it from escaping the chroot.
The sandboxed process is also provided a PID namespace (a way for a process to look like it’s standalone on the machine, or among a subset of processes), denying it the ability to use ptrace() or kill() other processes. ptrace() in particular is dangerous as it allows processes to read or manipulate data in other processes. Sandboxed processes are unable to ptrace() each other as well (set to undumpable).
A network namespace is used as well in order to prevent sandboxed processes from connecting out – not much documentation on this.
The Broker process, which remains unrestricted by SUID, is what handles decisions about downloading files, writing to the disk, etc. It handles the dangerous stuff, and is unrestricted, but it is separated from the areas of the program that are most open to attack. Using an Apparmor profile will allow restriction even of the broker process. Otherwise it remains confined purely by DAC.
The next layer of restriction is provided by the Seccomp-BPF sandbox. Seccomp filters are something I’ve written about before. Their goal isn’t to protect the system from damage, like the SUID sandbox does, but to protect the system from further exploitation.
Seccomp-BPF works by restricting the system calls that programs can make. The implications of this are covered in this post. A quick summary is that a sandbox, or any form of access control, is only as powerful as the kernel. It is very often the case that, rather than trying to find issues with the sandbox itself, an attacker can simply go after the big buggy kernel running underneath it. An attack on the kernel allows for a full bypass of the sandbox.*
Seccomp works by restricting access to the kernel by filtering the ‘calls’ that can be made to it. The fewer calls a program can make the fewer ways it can exploit the system. Suddenly the kernel isn’t this massive glob of attack surface, it’s a much smaller are, with monitored interaction between it and the program.
Chrome on Windows had its sandbox broken at Pwn2Own by MWRLabs. It was, in fact, a local kernel vulnerable that allowed them to bypass the sandbox once they’d gained access to the renderer. Such an attack would be far more difficult on a Linux system with Seccomp enabled.
Overall the sandbox works by reducing the potential for damage and reducing the potential for local exploitation. Chrome is, as always, pouring work into their security. Their sandbox is very impressive, and I would love to see some research into breaking it.
There was a ‘partial reward’ for PinkiePie exploiting ChromeOS, but it was unreliable. No details have been released yet, quite unfortunately.
*Plug for Grsecurity here. See my guide for setting up a hardened Grsec kernel. Seccomp limits kernel attack surface, Grsecurity makes the entire kernel more difficult to exploit.