-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Closed
Labels
Milestone
Description
It should be possible to use CLONE_NEWUSER from unprivileged user, but somehow it isn't. Code:
package main
import (
"log"
"os"
"os/exec"
"syscall"
)
func main() {
cmd := exec.Command(os.Args[1], os.Args[2:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Stdin = os.Stdin
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWUSER
cmd.SysProcAttr.UidMappings = []syscall.SysProcIDMap{
{ContainerID: 0, HostID: 1000, Size: 1},
}
cmd.SysProcAttr.GidMappings = []syscall.SysProcIDMap{
{ContainerID: 0, HostID: 1000, Size: 1},
}
if err := cmd.Run(); err != nil {
log.Fatal(err)
}
}
On ./unshare /bin/zsh returns
2015/04/29 20:14:55 fork/exec /bin/zsh: operation not permitted
Strace shows:
[pid 27482] open("/proc/27481/uid_map", O_RDWR <unfinished ...>
[pid 27480] <... select resumed> ) = 0 (Timeout)
[pid 27482] <... open resumed> ) = 5
[pid 27480] select(0, NULL, NULL, NULL, {0, 20} <unfinished ...>
[pid 27482] write(5, "0 1000 1\n\0", 10) = 10
[pid 27482] close(5) = 0
[pid 27480] <... select resumed> ) = 0 (Timeout)
[pid 27482] open("/proc/27481/gid_map", O_RDWR <unfinished ...>
[pid 27480] select(0, NULL, NULL, NULL, {0, 20} <unfinished ...>
[pid 27482] <... open resumed> ) = 5
[pid 27482] write(5, "0 1000 1\n\0", 10) = -1 EPERM (Operation not permitted)
Code similar to forkAndExecInChild from syscall/exec_linux.go is in man user_namespaces: https://gist.github.com/31920b19eb18cf4b507d
I compiled it with clang clone.c -o clone and run as ./clone -Uz /bin/zsh. It works from unprivileged user and mapping uids/gids inside namespace.
It is pretty cool feature, because it allows unprivileged users to create own namespaces.
ping @mrunalp as author of UidMappings.
For reproducing I used go from tag go1.4.2 on x86_64 Gentoo linux with 4.0.0 kernel.