@pati_gallardo
Turtle
Sec
Linux Security
and the Chromium Sandbox
Patricia Aas, TurtleSec
NDC Security 2019
@pati_gallardo
Turtle
Sec
Patricia Aas - Consultant
C++ Programmer, Application Security
Currently : TurtleSec
Previously : Vivaldi, Cisco Systems, Knowit, Opera Software
Master in Computer Science - main language Java
Pronouns: she/her Turtle
Sec
@pati_gallardo
Remote Code Execution
is what browsers do.
4
Sandboxing
- System External Threat :
Protect the system from the
vulnerabilities in the browser
- System Internal Threat : Protect
the browser from malware on the
system
@pati_gallardo
5
- Process Architecture
- Linux Security APIs
- The Initial Sandbox
- Shrinking the Sandbox
Outline
@pati_gallardo
6
Process
Architecture
@pati_gallardo
7
- vivaldi : The bash script wrapper,
launches vivaldi-bin. Sets up
environment.
- vivaldi-bin : The browser binary
- vivaldi-sandbox : A setuid
binary, not in much use today
The Executable Files
@pati_gallardo
8
Process Architecture
Browser
Gpu BrokerZygote
Renderer
GpuZygote Init
Renderer
Renderer
Process
Relationships
Tabs (ish)
@pati_gallardo
9
1. Browser :
vivaldi-bin
2. Zygote (Parent) :
vivaldi-bin --type=zygote
3. Zygote (Child) :
vivaldi-bin --type=zygote
4. Renderer (MANY) :
vivaldi-bin --type=renderer
5. GPU (Parent) :
vivaldi-bin --type=gpu-process
6. GPU Broker (Child) :
vivaldi-bin --type=gpu-broker
The Running Processes
@pati_gallardo
10
Outline
- Process Architecture
- Linux Security APIs
- The Initial Sandbox
- Shrinking the Sandbox
@pati_gallardo
11
Linux Security
APIs
@pati_gallardo
12
chrome://sandbox
@pati_gallardo
13
NS(User)
NS(Pid)NS(Net)Web
Network
Filesystem System Calls
chroot
seccomp, capset
Resources
setrlimit
- Process Architecture
- Linux Security APIs
- The Initial Sandbox
- Shrinking the Sandbox
Outline
@pati_gallardo
15
The
Initial
Sandbox
@pati_gallardo
16
One Binary
Browser
Gpu BrokerZygote
Renderer
GpuZygote Init
Clone/Exec
User/Pid/Net
Fork/Exec
ForkFork
Clone
@pati_gallardo
17
Initial Sandbox
Browser
Gpu BrokerZygote
Renderer
GpuZygote Init
Clone/Exec
User/Pid/Net
Fork/Exec
ForkFork
Clone
@pati_gallardo
18
- A typical start of a new process
on Linux is a “fork/exec”
- “Forking” is creating a new
process
- “Exec” is executing a binary in a
process
- “Clone” is a type of fork which
can restrict a process at creation
@pati_gallardo
19
Fork / Exec
The sandbox is
constructed in stages
20
1. Before Fork
2. After Fork
21
Sandboxing Opportunities: Fork
1. Before clone/fork
2. (At clone)
3. Before Exec
4. At startup (input : argv, env)22
Sandboxing Opportunities: “Fork”/exec
Namespaces
@pati_gallardo
23
Namespaces
(Zygotes/Renderers)
Limits what a process can see
Api : clone/unshare @pati_gallardo
24
CLONE_NEWUSER
Inside a USER NS we can create a PID NS.
CLONE_NEWPID
Same PID number can represent different
processes in different PID namespaces. One init
(PID 1) process per PID NS
CLONE_NEWNET
Isolate a process from network
Zygote + Renderer
@pati_gallardo
25
Namespaces in use
Clone flags define the process* created
and will create namespaces (NS) for it
1. Test which NS are available
2. Fail if not sufficient
3. Construct the biggest supported and
applicable set
Emulates fork with longjmp
* Also used to create threads
@pati_gallardo
26
At Clone : Create NAmespacesZygote + Renderer
int flags = CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET;
jmp_buf env;
if (setjmp(env) == 0) {
return CloneAndLongjmpInChild(flags, ptid, ctid, &env);
}
@pati_gallardo
chromium/base/process/launch_posix.cc
Code Simplified To Illustrate
27
pid_t CloneAndLongjmpInChild(unsigned long flags,
pid_t* ptid,
pid_t* ctid,
jmp_buf* env) {
char stack_buf[PTHREAD_STACK_MIN];
void* stack = stack_buf + sizeof(stack_buf);
return clone(&CloneHelper,
stack, flags, env, ptid, nullptr, ctid);
}
@pati_gallardo
chromium/base/process/launch_posix.cc
Code Simplified To Illustrate
28
int CloneHelper(void* arg) {
jmp_buf* env_ptr = reinterpret_cast<jmp_buf*>(arg);
longjmp(*env_ptr, 1);
// Should not be reached
assert(false);
return 1;
}
@pati_gallardo
chromium/base/process/launch_posix.cc
Code Simplified To Illustrate
29
unshare(CLONE_NEWUSER)
Alternative to clone(CLONE_NEWUSER), will
not create new process, but move caller.
Credentials::CanCreateProcessInNewUserNS
Zygote Parent
@pati_gallardo
30
Unshare- User Namespace
1. Before clone/fork
2. At clone
3. Before Exec
4. At startup (input : argv, env)31
Sandboxing Opportunities: “Fork”/exec
1. Fix the environment
2. Fix file descriptors
3. Fix signal handling
4. Set up process group
5. Maximize resource limits
6. Set PR_SET_NO_NEW_PRIVS
7. Change current dir
8. Select executable path
9. Setup command-line
GPU + Zygote
@pati_gallardo
32
Before Exec : Launch Options
Prepare for Exec
- Process Architecture
- Linux Security APIs
- The Initial Sandbox
- Shrinking the Sandbox
Outline
@pati_gallardo
33
Shrinking
the Sandbox
@pati_gallardo
34
Shrinking the Sandbox
@pati_gallardo
35
Browser
Gpu Broker
Seccomp
Zygote
SYS_ADMIN
Renderer
Pid capset rlimit
Gpu
Seccomp
Zygote Init
User capset chroot
Clone/Exec *
User/Pid/Net
Fork/Exec *
* NO_NEW_PRIVS
Done post fork
ForkFork
Clone
prctl(PR_SET_NO_NEW_PRIVS)
Preserved across fork, clone and execve
“If no_new_privs is set, then operations
that grant new privileges (i.e. execve) will
either fail or not grant them. This affects
suid/sgid, file capabilities, and LSMs.”
/usr/include/linux/prctl.h
All except Browser
@pati_gallardo
36
PR_SET_NO_NEW_PRIVS
Seccomp
@pati_gallardo
@pati_gallardo
37
Seccomp
(Renderers/GPU/Broker)
Limits which syscalls a process
can call and how these calls are
handled
Api : seccomp @pati_gallardo
38
Program written in an assembly-like
language to filter system-calls.
Runs in a simple VM in kernel space. All
syscalls will be filtered by this program
TSYNC : Once a Seccomp Program is
installed it applies to all threads in a
process
Renderer + Gpu + Broker
@pati_gallardo
39
Seccomp BPF Program
BPF Program defined in a Policy
Fundamentally a whitelist, allows a set of
syscalls and has custom handling of others.
An extended Policy is generally more
permissive
1. BaselinePolicy
1.1 GpuProcessPolicy
1.1.1 GpuBrokerProcessPolicy
1.2 RendererProcessPolicy
@pati_gallardo
40
Renderer + Gpu + Broker
Seccomp : BPF Policies
void StartSandboxWithPolicy(sandbox::bpf_dsl::Policy* policy)
{
SandboxBPF sandbox(policy);
assert(sandbox.StartSandbox());
}
bool SandboxBPF::StartSandbox() {
InstallFilter();
return true;
}
@pati_gallardo
chromium/services/service_manager/sandbox/linux/sandbox_seccomp_bpf_linux.cc
chromium/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
Code Simplified To Illustrate
41
void SandboxBPF::InstallFilter() {
CodeGen::Program program = AssembleFilter();
struct sock_filter bpf[program.size()];
const struct sock_fprog prog =
{ static_cast<unsigned short>(program.size()), bpf };
memcpy(bpf, &program[0], sizeof(bpf));
assert(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == 0);
assert(seccomp(SECCOMP_SET_MODE_FILTER,
SECCOMP_FILTER_FLAG_TSYNC, &prog) == 0);
}
@pati_gallardo
chromium/sandbox/linux/seccomp-bpf/sandbox_bpf.cc
Code Simplified To Illustrate
42
Chroot
@pati_gallardo
@pati_gallardo
43
Chroot
(Zygotes/Renderers)
Limits what a process can see of
the filesystem
Api : chroot @pati_gallardo
44
- clone(CLONE_FS) a child process
- Child chroot(”/proc/self/fdinfo/”)
- Child immediately does a chdir(“/”)
- Child does _exit(kExitSuccess)
You can see this by looking at
ls -l /proc/<pid>/root
Of the Zygote or any ancestor
Credentials::DropFileSystemAccess
Zygotes + Renderer
@pati_gallardo
45
Chroot : Drop Access to FS
bool ChrootToSafeEmptyDir() {
pid_t pid = -1;
char stack_buf[PTHREAD_STACK_MIN];
void* stack = stack_buf + sizeof(stack_buf);
int clone_flags = CLONE_FS | LINUX_SIGCHLD;
pid = clone(ChrootToSelfFdinfo, stack, clone_flags, nullptr);
int status = -1;
assert(HANDLE_EINTR(waitpid(pid, &status, 0)) == pid);
return WIFEXITED(status) && WEXITSTATUS(status) == kExitSuccess;
}
@pati_gallardo
chromium/sandbox/linux/services/credentials.cc
Code Simplified To Illustrate
46
int ChrootToSelfFdinfo(void*) {
assert(chroot("/proc/self/fdinfo/") == 0);
assert(chdir("/") == 0);
_exit(kExitSuccess);
}
@pati_gallardo
chromium/sandbox/linux/services/credentials.cc
Code Simplified To Illustrate
47
Capabilities
@pati_gallardo
@pati_gallardo
48
Capabilities
(Zygote/Renderers)
Limits what a process is
privileged enough to do
Api : capset @pati_gallardo
49
Uses capset() to drop all or some
capabilities
“Linux divides the privileges traditionally
associated with superuser into distinct
units, known as capabilities, which can be
independently enabled and disabled.”
Man page for capabilities
Credentials::DropAllCapabilities
Zygotes + Renderers
@pati_gallardo
50
Drop Capabilities
Resource Limits
@pati_gallardo
51
Resource Limits
(Renderers)
Limits the access this process
has to platform resources
Api : setrlimit @pati_gallardo
52
Limits using setrlimit:
1. RLIMIT_AS : Maximum size of the
process’ virtual memory (address
space) in bytes
2. RLIMIT_DATA : Maximum size of
the process's data segment
LinuxSandbox::LimitAddressSpace
Renderer
@pati_gallardo
53
Resource Limits : setrlimit
Trust is Relative
Browser
Gpu Broker
Seccomp
Zygote
SYS_ADMIN
Renderer
Pid capset rlimit
Gpu
Seccomp
Zygote Init
User capset chroot
Clone/Exec *
User/Pid/Net
Fork/Exec *
* NO_NEW_PRIVS
Done post fork
ForkFork
Clone No access to
filesystem
@pati_gallardo
54
@pati_gallardo
chrome://sandbox
@pati_gallardo
55
Sources
Chromium/Kernel source + Linux Man Pages + lwn.net
Michael Kerrisk
Book: The Linux Programming Interface
Course: Linux Security and Isolation APIs
All Errors Are My Own
56
Patricia Aas, Consultant
TurtleSec
C++ and Application Security
Turtle
Sec
@pati_gallardo
@pati_gallardo
@pati_gallardo
Turtle
Sec
Appendix / Some Notes
@pati_gallardo
Other APIs
in use
@pati_gallardo
60
Not Used Much in Chromium, but...
61
YAMA LSM
Limits the access that other
process have to this process -
especially ptracing
Status is checked by reading :
/proc/sys/kernel/yama/ptrace_scope
@pati_gallardo
62
Setuid/setgid
(Legacy)
Increases what a process is
privileged enough to do, by
using the privilege of the
executables owner
Api : set*uid / set*gid @pati_gallardo
63
CGroups
(ChromeOS)
Limits the resources available to
a process. Used in ChromeOS -
not covered here.
/proc/<PID>/cgroup
/proc/cgroups
@pati_gallardo
64
Process Groups
(Chromedriver)
Can be used to treat a group of
processes as one.
Used with the ‘detach’ property
of Chromedriver
Api : setpgid @pati_gallardo
65
Challenges
@pati_gallardo
66
Debugging
@pati_gallardo
Crash Reporting @pati_gallardo
Photos from pixabay.com
Patricia Aas, TurtleSec
@pati_gallardo
Turtle
Sec
@pati_gallardo
@pati_gallardo
Turtle
Sec

Chromium Sandbox on Linux (NDC Security 2019)