Linux Security APIs and the Chromium Sandbox (SwedenCpp Meetup 2017)
- 2. Linux Security
and How Web Browser Sandboxes Really Work
Patricia Aas
SweedenCpp Meetup C++ Stockholm 0x08 2017
@pati_gallardo
- 3. Patricia Aas
Programmer - mainly in C++ and Java
Currently : Vivaldi Technologies
Previously : Cisco Systems, Knowit, Opera Software
Master in Computer Science
Twitter : @pati_gallardo
- 7. Namespaces in use
CLONE_NEWUSER
No privilege is needed to create a USER NS, and
in one we can create a PID NS without global
privilege.
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
@pati_gallardo
Zygote + Renderer
- 8. At Clone : Create NAmespaces
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
Zygote + Renderer
- 9. 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
- 10. 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
- 11. 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
- 13. Shrinking the Sandbox
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
- 14. Seccomp BPF Program
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@pati_gallardo
Renderer + Gpu + Broker
- 15. Seccomp : BPF Policies
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
Renderer + Gpu + Broker
- 17. 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
- 18. Chroot : Drop Access to FS
- 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@pati_gallardo
Zygotes + Renderer
- 19. 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
- 21. 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
- 23. Sources
Michael Kerrisk
Book: The Linux Programming Interface
Course: Linux Security and Isolation APIs
Chromium/Kernel source + Linux Man Pages + lwn.net
All Errors Are My Own
- 24. Linux Security
and How Web Browser Sandboxes Really Work
Patricia Aas, Vivaldi Technologies
@pati_gallardo
Photos from pixabay.com