Support the unprivileged namespace sandbox
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Oxide |
Triaged
|
High
|
Chris Coulson | ||
chromium-browser (Ubuntu) |
Confirmed
|
Undecided
|
Unassigned | ||
evince (Ubuntu) |
Confirmed
|
Undecided
|
Unassigned |
Bug Description
Chromium has a new layer 1 sandbox which replaces the suid sandbox on systems with CLONE_NEWUSER. However, it's currently incompatible with application confinement.
To summarize, the sandbox mechanism does something like this:
1) Browser launches zygote process:
- clones with CLONE_NEWUSER | CLONE_NEWPID | CLONE_NEWNET and then exec()
2) Zygote initializes sandbox:
- unshare(
- clones a new process with CLONE_FS and then does waitpid(). The child chroots to /proc/self/fdinfo
- Enables CAP_SYS_ADMIN (see below)
3) Zygote forks
- Parent becomes init
- Child continues as zygote
4) Zygote waits for requests from the browser to create render processes
5) On each request:
- Zygote clones a new process with CLONE_NEWPID (this is why it needs CAP_SYS_ADMIN)
- New process drops all privileges and becomes a renderer
This produces the following denial on the device:
type=1400 audit(142973398
The oxide_helper profile already allows sys_admin, but this is coming from the browser process, just here:
7229 clone(child_
7246 exit_group(0) = ?
7229 wait4(7246, <unfinished ...>
7246 +++ exited with 0 +++
7229 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 7246
7229 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=7246, si_status=0, si_utime=0, si_stime=0} ---
7229 write(13, "\0", 1) = 1
7229 rt_sigreturn() = 7246
7229 access(
7229 access(
7229 access(
7229 access(
7229 access(
7229 getuid32() = 32011
7229 getgid32() = 32011
7229 access(
7229 rt_sigprocmask(
7229 clone(child_
It fails in step 1) above, because it needs CAP_SYS_ADMIN before it's able to transition to the oxide_helper profile (which allows it)
Changed in oxide: | |
status: | New → Triaged |
importance: | Undecided → High |
Changed in oxide: | |
milestone: | none → branch-1.9 |
Changed in oxide: | |
milestone: | branch-1.9 → branch-1.11 |
Changed in oxide: | |
milestone: | branch-1.11 → branch-1.12 |
Changed in oxide: | |
assignee: | nobody → Chris Coulson (chrisccoulson) |
Changed in chromium-browser (Ubuntu): | |
assignee: | nobody → Chad Miller (cmiller) |
Changed in oxide: | |
milestone: | branch-1.12 → branch-1.13 |
Changed in oxide: | |
milestone: | branch-1.13 → branch-1.15 |
Changed in oxide: | |
milestone: | branch-1.15 → branch-1.16 |
Changed in oxide: | |
milestone: | branch-1.16 → branch-1.17 |
Changed in oxide: | |
milestone: | branch-1.17 → branch-1.18 |
Changed in oxide: | |
milestone: | branch-1.18 → branch-1.19 |
Changed in oxide: | |
milestone: | branch-1.19 → branch-1.20 |
Changed in oxide: | |
milestone: | branch-1.20 → branch-1.21 |
Changed in oxide: | |
milestone: | branch-1.21 → branch-1.22 |
Changed in oxide: | |
milestone: | branch-1.22 → branch-1.23 |
Changed in chromium-browser (Ubuntu): | |
assignee: | Chad Miller (cmiller) → nobody |
I've done some testing with a little test program and basic AppArmor confinement. When an unconfined and unprivileged process enters a new user and pid namespace, it picks up all capabilities. When a confined and unprivileged process enters a new user and pid namespace, it only picks up the capabilities that are listed in the AppArmor profile.