diff --git a/main.go b/main.go index 4dfe0a5..a37dadf 100644 --- a/main.go +++ b/main.go @@ -5,16 +5,17 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "runtime" "strings" - "github.com/Sirupsen/logrus" aaprofile "github.com/docker/docker/profiles/apparmor" "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/apparmor" _ "github.com/opencontainers/runc/libcontainer/nsenter" - "github.com/opencontainers/runc/libcontainer/user" - "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/runc/libcontainer/specconv" + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" ) const ( @@ -40,15 +41,14 @@ const ( ) var ( - console = os.Getenv("console") containerID string pidFile string root string - allocateTty bool - detach bool - readonly bool - useSystemdCgroup bool + allocateTty bool + consoleSocket string + detach bool + readonly bool hooks specs.Hooks hookflags stringSlice @@ -113,16 +113,14 @@ func (s stringSlice) ParseHooks() (hooks specs.Hooks, err error) { func init() { // Parse flags flag.StringVar(&containerID, "id", IMAGE, "container ID") - flag.StringVar(&console, "console", console, "the pty slave path for use with the container") flag.StringVar(&pidFile, "pid-file", "", "specify the file to write the process id to") flag.StringVar(&root, "root", defaultRoot, "root directory of container state, should be tmpfs") flag.Var(&hookflags, "hook", "Hooks to prefill into spec file. (ex. --hook prestart:netns)") flag.BoolVar(&allocateTty, "t", true, "allocate a tty for the container") + flag.StringVar(&consoleSocket, "console-socket", "", "path to an AF_UNIX socket which will receive a file descriptor referencing the master end of the console's pseudoterminal") flag.BoolVar(&detach, "d", false, "detach from the container's process") - // TODO (jess): do not enable this flag, the error is very gross on systemd - // flag.BoolVar(&useSystemdCgroup, "systemd-cgroup", false, "enable systemd cgroup support") flag.BoolVar(&readonly, "read-only", false, "make container filesystem readonly") flag.BoolVar(&version, "version", false, "print version and exit") @@ -141,17 +139,33 @@ func init() { os.Exit(0) } - // Set log level + // Set log level. if debug { logrus.SetLevel(logrus.DebugLevel) } - // parse the hook flags + // Parse the hook flags. var err error hooks, err = hookflags.ParseHooks() if err != nil { logrus.Fatal(err) } + + // Convert pid-file to an absolute path so we can write to the + // right file after chdir to bundle. + if pidFile != "" { + pidFile, err = filepath.Abs(pidFile) + if err != nil { + logrus.Fatal(err) + } + } + + // Get the absolute path to the root. + root, err = filepath.Abs(root) + if err != nil { + logrus.Fatal(err) + } + } //go:generate go run generate.go @@ -161,28 +175,27 @@ func main() { return } - notifySocket := os.Getenv("NOTIFY_SOCKET") - if notifySocket != "" { - setupSdNotify(spec, notifySocket) - } + // Initialize the spec. + spec := specconv.Example() - // override the cmd in the spec with any args specified - if len(flag.Args()) > 0 { - spec.Process.Args = flag.Args() - } + // Set the spec to be rootless. + specconv.ToRootless(spec) - // setup readonly fs in spec + // Setup readonly fs in spec. spec.Root.Readonly = readonly - // setup tty in spec + // Setup tty in spec. spec.Process.Terminal = allocateTty - // pass in any hooks - spec.Hooks = hooks + // Pass in any hooks to the spec. + spec.Hooks = &hooks - // install the default apparmor profile + // Set the default seccomp profile. + spec.Linux.Seccomp = defaultSeccompProfile + + // Install the default apparmor profile. if apparmor.IsEnabled() { - // check if we have the docker-default apparmor profile loaded + // Check if we have the docker-default apparmor profile loaded. if _, err := aaprofile.IsLoaded(defaultApparmorProfile); err != nil { logrus.Warnf("AppArmor enabled on system but the %s profile is not loaded. apparmor_parser needs root to load a profile so we can't do it for you.", defaultApparmorProfile) } else { @@ -190,45 +203,23 @@ func main() { } } - // set the CgroupsPath as this user - u, err := user.CurrentUser() - if err != nil { - logrus.Fatal(err) - } - spec.Linux.CgroupsPath = sPtr(u.Name) - - // setup UID mappings - spec.Linux.UIDMappings = []specs.IDMapping{ - { - HostID: uint32(u.Uid), - ContainerID: 0, - Size: 1, - }, - } - - // setup GID mappings - spec.Linux.GIDMappings = []specs.IDMapping{ - { - HostID: uint32(u.Gid), - ContainerID: 0, - Size: 1, - }, - } - + // Unpack the rootfs. if err := unpackRootfs(spec); err != nil { logrus.Fatal(err) } - status, err := startContainer(spec, containerID, pidFile, detach, useSystemdCgroup) + // Start the container. + status, err := startContainer(spec, containerID, pidFile, consoleSocket, root, detach) if err != nil { logrus.Fatal(err) } + // Remove the rootfs after the container has exited. if err := os.RemoveAll(defaultRootfsDir); err != nil { logrus.Warnf("removing rootfs failed: %v", err) } - // exit with the container's exit status + // Exit with the container's exit status. os.Exit(status) } diff --git a/notify_socket.go b/notify_socket.go new file mode 100644 index 0000000..98bb14d --- /dev/null +++ b/notify_socket.go @@ -0,0 +1,106 @@ +package main + +import ( + "bytes" + "fmt" + "net" + "os" + "path/filepath" + + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" +) + +type notifySocket struct { + socket *net.UnixConn + host string + socketPath string +} + +func newNotifySocket(id, root string) *notifySocket { + if os.Getenv("NOTIFY_SOCKET") == "" { + // Return early if we do not have a NOTIFY_SOCKET. + return nil + } + + path := filepath.Join(filepath.Join(root, id), "notify.sock") + + notifySocket := ¬ifySocket{ + socket: nil, + host: os.Getenv("NOTIFY_SOCKET"), + socketPath: path, + } + + return notifySocket +} + +func (s *notifySocket) Close() error { + return s.socket.Close() +} + +// If systemd is supporting sd_notify protocol, this function will add support +// for sd_notify protocol from within the container. +func (s *notifySocket) setupSpec(spec *specs.Spec) { + mount := specs.Mount{Destination: s.host, Type: "bind", Source: s.socketPath, Options: []string{"bind"}} + spec.Mounts = append(spec.Mounts, mount) + spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", s.host)) +} + +func (s *notifySocket) setupSocket() error { + addr := net.UnixAddr{ + Name: s.socketPath, + Net: "unixgram", + } + + socket, err := net.ListenUnixgram("unixgram", &addr) + if err != nil { + return err + } + + s.socket = socket + return nil +} + +// pid1 must be set only with -d, as it is used to set the new process as the main process +// for the service in butts +func (notifySocket *notifySocket) run(pid1 int) { + buf := make([]byte, 512) + notifySocketHostAddr := net.UnixAddr{Name: notifySocket.host, Net: "unixgram"} + client, err := net.DialUnix("unixgram", nil, ¬ifySocketHostAddr) + if err != nil { + logrus.Error(err) + return + } + for { + r, err := notifySocket.socket.Read(buf) + if err != nil { + break + } + var out bytes.Buffer + for _, line := range bytes.Split(buf[0:r], []byte{'\n'}) { + if bytes.HasPrefix(line, []byte("READY=")) { + _, err = out.Write(line) + if err != nil { + return + } + + _, err = out.Write([]byte{'\n'}) + if err != nil { + return + } + + _, err = client.Write(out.Bytes()) + if err != nil { + return + } + + // now we can inform butts to use pid1 as the pid to monitor + if pid1 > 0 { + newPid := fmt.Sprintf("MAINPID=%d\n", pid1) + client.Write([]byte(newPid)) + } + return + } + } + } +} diff --git a/rlimit_linux.go b/rlimit_linux.go index 0de8b0b..c97a0fb 100644 --- a/rlimit_linux.go +++ b/rlimit_linux.go @@ -43,7 +43,7 @@ var rlimitMap = map[string]int{ func strToRlimit(key string) (int, error) { rl, ok := rlimitMap[key] if !ok { - return 0, fmt.Errorf("Wrong rlimit value: %s", key) + return 0, fmt.Errorf("wrong rlimit value: %s", key) } return rl, nil } diff --git a/rootfs_ops.go b/rootfs_ops.go index 7c9b436..f899c94 100644 --- a/rootfs_ops.go +++ b/rootfs_ops.go @@ -22,7 +22,7 @@ func unpackRootfs(spec *specs.Spec) error { } r := bytes.NewReader(data) - if err := archive.Untar(r, defaultRootfsDir, nil); err != nil { + if err := archive.Untar(r, defaultRootfsDir, &archive.TarOptions{NoLchown: true}); err != nil { return err } diff --git a/seccomp.go b/seccomp.go index a86cbed..b41c817 100644 --- a/seccomp.go +++ b/seccomp.go @@ -32,99 +32,99 @@ func arches() []specs.Arch { } // defaultProfile defines the whitelist for the default seccomp profile. -var defaultSeccompProfile = &specs.Seccomp{ +var defaultSeccompProfile = &specs.LinuxSeccomp{ DefaultAction: specs.ActErrno, Architectures: arches(), - Syscalls: []specs.Syscall{ + Syscalls: []specs.LinuxSyscall{ { - Name: "accept", + Names: []string{"accept"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "accept4", + Names: []string{"accept4"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "access", + Names: []string{"access"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "alarm", + Names: []string{"alarm"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "arch_prctl", + Names: []string{"arch_prctl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "bind", + Names: []string{"bind"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "brk", + Names: []string{"brk"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "capget", + Names: []string{"capget"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "capset", + Names: []string{"capset"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "chdir", + Names: []string{"chdir"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "chmod", + Names: []string{"chmod"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "chown", + Names: []string{"chown"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "chown32", + Names: []string{"chown32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "chroot", + Names: []string{"chroot"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "clock_getres", + Names: []string{"clock_getres"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "clock_gettime", + Names: []string{"clock_gettime"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "clock_nanosleep", + Names: []string{"clock_nanosleep"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "clone", + Names: []string{"clone"}, Action: specs.ActAllow, - Args: []specs.Arg{ + Args: []specs.LinuxSeccompArg{ { Index: 0, Value: syscall.CLONE_NEWNS | syscall.CLONE_NEWUTS | syscall.CLONE_NEWIPC | syscall.CLONE_NEWUSER | syscall.CLONE_NEWPID | syscall.CLONE_NEWNET, @@ -134,754 +134,754 @@ var defaultSeccompProfile = &specs.Seccomp{ }, }, { - Name: "close", + Names: []string{"close"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "connect", + Names: []string{"connect"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "copy_file_range", + Names: []string{"copy_file_range"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "creat", + Names: []string{"creat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "dup", + Names: []string{"dup"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "dup2", + Names: []string{"dup2"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "dup3", + Names: []string{"dup3"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "epoll_create", + Names: []string{"epoll_create"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "epoll_create1", + Names: []string{"epoll_create1"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "epoll_ctl", + Names: []string{"epoll_ctl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "epoll_ctl_old", + Names: []string{"epoll_ctl_old"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "epoll_pwait", + Names: []string{"epoll_pwait"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "epoll_wait", + Names: []string{"epoll_wait"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "epoll_wait_old", + Names: []string{"epoll_wait_old"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "eventfd", + Names: []string{"eventfd"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "eventfd2", + Names: []string{"eventfd2"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "execve", + Names: []string{"execve"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "execveat", + Names: []string{"execveat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "exit", + Names: []string{"exit"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "exit_group", + Names: []string{"exit_group"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "faccessat", + Names: []string{"faccessat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fadvise64", + Names: []string{"fadvise64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fadvise64_64", + Names: []string{"fadvise64_64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fallocate", + Names: []string{"fallocate"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fanotify_init", + Names: []string{"fanotify_init"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fanotify_mark", + Names: []string{"fanotify_mark"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fchdir", + Names: []string{"fchdir"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fchmod", + Names: []string{"fchmod"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fchmodat", + Names: []string{"fchmodat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fchown", + Names: []string{"fchown"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fchown32", + Names: []string{"fchown32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fchownat", + Names: []string{"fchownat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fcntl", + Names: []string{"fcntl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fcntl64", + Names: []string{"fcntl64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fdatasync", + Names: []string{"fdatasync"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fgetxattr", + Names: []string{"fgetxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "flistxattr", + Names: []string{"flistxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "flock", + Names: []string{"flock"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fork", + Names: []string{"fork"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fremovexattr", + Names: []string{"fremovexattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fsetxattr", + Names: []string{"fsetxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fstat", + Names: []string{"fstat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fstat64", + Names: []string{"fstat64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fstatat64", + Names: []string{"fstatat64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fstatfs", + Names: []string{"fstatfs"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fstatfs64", + Names: []string{"fstatfs64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "fsync", + Names: []string{"fsync"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ftruncate", + Names: []string{"ftruncate"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ftruncate64", + Names: []string{"ftruncate64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "futex", + Names: []string{"futex"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "futimesat", + Names: []string{"futimesat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getcpu", + Names: []string{"getcpu"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getcwd", + Names: []string{"getcwd"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getdents", + Names: []string{"getdents"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getdents64", + Names: []string{"getdents64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getegid", + Names: []string{"getegid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getegid32", + Names: []string{"getegid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "geteuid", + Names: []string{"geteuid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "geteuid32", + Names: []string{"geteuid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getgid", + Names: []string{"getgid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getgid32", + Names: []string{"getgid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getgroups", + Names: []string{"getgroups"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getgroups32", + Names: []string{"getgroups32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getitimer", + Names: []string{"getitimer"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getpeername", + Names: []string{"getpeername"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getpgid", + Names: []string{"getpgid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getpgrp", + Names: []string{"getpgrp"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getpid", + Names: []string{"getpid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getppid", + Names: []string{"getppid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getpriority", + Names: []string{"getpriority"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getrandom", + Names: []string{"getrandom"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getresgid", + Names: []string{"getresgid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getresgid32", + Names: []string{"getresgid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getresuid", + Names: []string{"getresuid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getresuid32", + Names: []string{"getresuid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getrlimit", + Names: []string{"getrlimit"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "get_robust_list", + Names: []string{"get_robust_list"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getrusage", + Names: []string{"getrusage"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getsid", + Names: []string{"getsid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getsockname", + Names: []string{"getsockname"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getsockopt", + Names: []string{"getsockopt"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "get_thread_area", + Names: []string{"get_thread_area"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "gettid", + Names: []string{"gettid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "gettimeofday", + Names: []string{"gettimeofday"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getuid", + Names: []string{"getuid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getuid32", + Names: []string{"getuid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "getxattr", + Names: []string{"getxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "inotify_add_watch", + Names: []string{"inotify_add_watch"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "inotify_init", + Names: []string{"inotify_init"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "inotify_init1", + Names: []string{"inotify_init1"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "inotify_rm_watch", + Names: []string{"inotify_rm_watch"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "io_cancel", + Names: []string{"io_cancel"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ioctl", + Names: []string{"ioctl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "io_destroy", + Names: []string{"io_destroy"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "io_getevents", + Names: []string{"io_getevents"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ioprio_get", + Names: []string{"ioprio_get"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ioprio_set", + Names: []string{"ioprio_set"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "io_setup", + Names: []string{"io_setup"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "io_submit", + Names: []string{"io_submit"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ipc", + Names: []string{"ipc"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "kill", + Names: []string{"kill"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lchown", + Names: []string{"lchown"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lchown32", + Names: []string{"lchown32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lgetxattr", + Names: []string{"lgetxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "link", + Names: []string{"link"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "linkat", + Names: []string{"linkat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "listen", + Names: []string{"listen"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "listxattr", + Names: []string{"listxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "llistxattr", + Names: []string{"llistxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "_llseek", + Names: []string{"_llseek"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lremovexattr", + Names: []string{"lremovexattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lseek", + Names: []string{"lseek"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lsetxattr", + Names: []string{"lsetxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lstat", + Names: []string{"lstat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "lstat64", + Names: []string{"lstat64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "madvise", + Names: []string{"madvise"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "memfd_create", + Names: []string{"memfd_create"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mincore", + Names: []string{"mincore"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mkdir", + Names: []string{"mkdir"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mkdirat", + Names: []string{"mkdirat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mknod", + Names: []string{"mknod"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mknodat", + Names: []string{"mknodat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mlock", + Names: []string{"mlock"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mlock2", + Names: []string{"mlock2"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mlockall", + Names: []string{"mlockall"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mmap", + Names: []string{"mmap"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mmap2", + Names: []string{"mmap2"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mprotect", + Names: []string{"mprotect"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mq_getsetattr", + Names: []string{"mq_getsetattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mq_notify", + Names: []string{"mq_notify"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mq_open", + Names: []string{"mq_open"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mq_timedreceive", + Names: []string{"mq_timedreceive"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mq_timedsend", + Names: []string{"mq_timedsend"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mq_unlink", + Names: []string{"mq_unlink"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "mremap", + Names: []string{"mremap"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "msgctl", + Names: []string{"msgctl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "msgget", + Names: []string{"msgget"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "msgrcv", + Names: []string{"msgrcv"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "msgsnd", + Names: []string{"msgsnd"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "msync", + Names: []string{"msync"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "munlock", + Names: []string{"munlock"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "munlockall", + Names: []string{"munlockall"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "munmap", + Names: []string{"munmap"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "nanosleep", + Names: []string{"nanosleep"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "newfstatat", + Names: []string{"newfstatat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "_newselect", + Names: []string{"_newselect"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "open", + Names: []string{"open"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "openat", + Names: []string{"openat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "pause", + Names: []string{"pause"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "personality", + Names: []string{"personality"}, Action: specs.ActAllow, - Args: []specs.Arg{ + Args: []specs.LinuxSeccompArg{ { Index: 0, Value: 0x0, @@ -890,9 +890,9 @@ var defaultSeccompProfile = &specs.Seccomp{ }, }, { - Name: "personality", + Names: []string{"personality"}, Action: specs.ActAllow, - Args: []specs.Arg{ + Args: []specs.LinuxSeccompArg{ { Index: 0, Value: 0x0008, @@ -901,9 +901,9 @@ var defaultSeccompProfile = &specs.Seccomp{ }, }, { - Name: "personality", + Names: []string{"personality"}, Action: specs.ActAllow, - Args: []specs.Arg{ + Args: []specs.LinuxSeccompArg{ { Index: 0, Value: 0xffffffff, @@ -912,741 +912,741 @@ var defaultSeccompProfile = &specs.Seccomp{ }, }, { - Name: "pipe", + Names: []string{"pipe"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "pipe2", + Names: []string{"pipe2"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "poll", + Names: []string{"poll"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ppoll", + Names: []string{"ppoll"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "prctl", + Names: []string{"prctl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "pread64", + Names: []string{"pread64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "preadv", + Names: []string{"preadv"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "prlimit64", + Names: []string{"prlimit64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "pselect6", + Names: []string{"pselect6"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "pwrite64", + Names: []string{"pwrite64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "pwritev", + Names: []string{"pwritev"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "read", + Names: []string{"read"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "readahead", + Names: []string{"readahead"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "readlink", + Names: []string{"readlink"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "readlinkat", + Names: []string{"readlinkat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "readv", + Names: []string{"readv"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "recv", + Names: []string{"recv"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "recvfrom", + Names: []string{"recvfrom"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "recvmmsg", + Names: []string{"recvmmsg"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "recvmsg", + Names: []string{"recvmsg"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "remap_file_pages", + Names: []string{"remap_file_pages"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "removexattr", + Names: []string{"removexattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rename", + Names: []string{"rename"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "renameat", + Names: []string{"renameat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "renameat2", + Names: []string{"renameat2"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "restart_syscall", + Names: []string{"restart_syscall"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rmdir", + Names: []string{"rmdir"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_sigaction", + Names: []string{"rt_sigaction"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_sigpending", + Names: []string{"rt_sigpending"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_sigprocmask", + Names: []string{"rt_sigprocmask"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_sigqueueinfo", + Names: []string{"rt_sigqueueinfo"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_sigreturn", + Names: []string{"rt_sigreturn"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_sigsuspend", + Names: []string{"rt_sigsuspend"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_sigtimedwait", + Names: []string{"rt_sigtimedwait"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "rt_tgsigqueueinfo", + Names: []string{"rt_tgsigqueueinfo"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_getaffinity", + Names: []string{"sched_getaffinity"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_getattr", + Names: []string{"sched_getattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_getparam", + Names: []string{"sched_getparam"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_get_priority_max", + Names: []string{"sched_get_priority_max"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_get_priority_min", + Names: []string{"sched_get_priority_min"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_getscheduler", + Names: []string{"sched_getscheduler"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_rr_get_interval", + Names: []string{"sched_rr_get_interval"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_setaffinity", + Names: []string{"sched_setaffinity"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_setattr", + Names: []string{"sched_setattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_setparam", + Names: []string{"sched_setparam"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_setscheduler", + Names: []string{"sched_setscheduler"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sched_yield", + Names: []string{"sched_yield"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "seccomp", + Names: []string{"seccomp"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "select", + Names: []string{"select"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "semctl", + Names: []string{"semctl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "semget", + Names: []string{"semget"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "semop", + Names: []string{"semop"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "semtimedop", + Names: []string{"semtimedop"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "send", + Names: []string{"send"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sendfile", + Names: []string{"sendfile"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sendfile64", + Names: []string{"sendfile64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sendmmsg", + Names: []string{"sendmmsg"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sendmsg", + Names: []string{"sendmsg"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sendto", + Names: []string{"sendto"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setdomainname", + Names: []string{"setdomainname"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setfsgid", + Names: []string{"setfsgid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setfsgid32", + Names: []string{"setfsgid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setfsuid", + Names: []string{"setfsuid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setfsuid32", + Names: []string{"setfsuid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setgid", + Names: []string{"setgid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setgid32", + Names: []string{"setgid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setgroups", + Names: []string{"setgroups"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setgroups32", + Names: []string{"setgroups32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sethostname", + Names: []string{"sethostname"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setitimer", + Names: []string{"setitimer"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setpgid", + Names: []string{"setpgid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setpriority", + Names: []string{"setpriority"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setregid", + Names: []string{"setregid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setregid32", + Names: []string{"setregid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setresgid", + Names: []string{"setresgid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setresgid32", + Names: []string{"setresgid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setresuid", + Names: []string{"setresuid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setresuid32", + Names: []string{"setresuid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setreuid", + Names: []string{"setreuid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setreuid32", + Names: []string{"setreuid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setrlimit", + Names: []string{"setrlimit"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "set_robust_list", + Names: []string{"set_robust_list"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setsid", + Names: []string{"setsid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setsockopt", + Names: []string{"setsockopt"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "set_thread_area", + Names: []string{"set_thread_area"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "set_tid_address", + Names: []string{"set_tid_address"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setuid", + Names: []string{"setuid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setuid32", + Names: []string{"setuid32"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "setxattr", + Names: []string{"setxattr"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "shmat", + Names: []string{"shmat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "shmctl", + Names: []string{"shmctl"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "shmdt", + Names: []string{"shmdt"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "shmget", + Names: []string{"shmget"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "shutdown", + Names: []string{"shutdown"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sigaltstack", + Names: []string{"sigaltstack"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "signalfd", + Names: []string{"signalfd"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "signalfd4", + Names: []string{"signalfd4"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sigreturn", + Names: []string{"sigreturn"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "socket", + Names: []string{"socket"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "socketpair", + Names: []string{"socketpair"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "splice", + Names: []string{"splice"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "stat", + Names: []string{"stat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "stat64", + Names: []string{"stat64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "statfs", + Names: []string{"statfs"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "statfs64", + Names: []string{"statfs64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "symlink", + Names: []string{"symlink"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "symlinkat", + Names: []string{"symlinkat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sync", + Names: []string{"sync"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sync_file_range", + Names: []string{"sync_file_range"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "syncfs", + Names: []string{"syncfs"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "sysinfo", + Names: []string{"sysinfo"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "syslog", + Names: []string{"syslog"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "tee", + Names: []string{"tee"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "tgkill", + Names: []string{"tgkill"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "time", + Names: []string{"time"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timer_create", + Names: []string{"timer_create"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timer_delete", + Names: []string{"timer_delete"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timerfd_create", + Names: []string{"timerfd_create"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timerfd_gettime", + Names: []string{"timerfd_gettime"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timerfd_settime", + Names: []string{"timerfd_settime"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timer_getoverrun", + Names: []string{"timer_getoverrun"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timer_gettime", + Names: []string{"timer_gettime"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "timer_settime", + Names: []string{"timer_settime"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "times", + Names: []string{"times"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "tkill", + Names: []string{"tkill"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "truncate", + Names: []string{"truncate"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "truncate64", + Names: []string{"truncate64"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "ugetrlimit", + Names: []string{"ugetrlimit"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "umask", + Names: []string{"umask"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "uname", + Names: []string{"uname"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "unlink", + Names: []string{"unlink"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "unlinkat", + Names: []string{"unlinkat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "utime", + Names: []string{"utime"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "utimensat", + Names: []string{"utimensat"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "utimes", + Names: []string{"utimes"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "vfork", + Names: []string{"vfork"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "vhangup", + Names: []string{"vhangup"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "vmsplice", + Names: []string{"vmsplice"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "wait4", + Names: []string{"wait4"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "waitid", + Names: []string{"waitid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "waitpid", + Names: []string{"waitpid"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "write", + Names: []string{"write"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "writev", + Names: []string{"writev"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, // i386 specific syscalls { - Name: "modify_ldt", + Names: []string{"modify_ldt"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, // arm specific syscalls { - Name: "breakpoint", + Names: []string{"breakpoint"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "cacheflush", + Names: []string{"cacheflush"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, { - Name: "set_tls", + Names: []string{"set_tls"}, Action: specs.ActAllow, - Args: []specs.Arg{}, + Args: []specs.LinuxSeccompArg{}, }, }, } diff --git a/signals.go b/signals.go index 563749e..0dde1c6 100644 --- a/signals.go +++ b/signals.go @@ -3,19 +3,23 @@ package main import ( "os" "os/signal" - "syscall" + "syscall" // only for Signal - "github.com/Sirupsen/logrus" "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/system" "github.com/opencontainers/runc/libcontainer/utils" + + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) const signalBufferSize = 2048 // newSignalHandler returns a signal handler for processing SIGCHLD and SIGWINCH signals // while still forwarding all other signals to the process. -func newSignalHandler(tty *tty, enableSubreaper bool) *signalHandler { +// If notifySocket is present, use it to read butts notifications from the container and +// forward them to notifySocketHost. +func newSignalHandler(enableSubreaper bool, notifySocket *notifySocket) *signalHandler { if enableSubreaper { // set us as the subreaper before registering the signal handler for the container if err := system.SetSubreaper(1); err != nil { @@ -28,8 +32,8 @@ func newSignalHandler(tty *tty, enableSubreaper bool) *signalHandler { // handle all signals for the process. signal.Notify(s) return &signalHandler{ - tty: tty, - signals: s, + signals: s, + notifySocket: notifySocket, } } @@ -41,26 +45,43 @@ type exit struct { } type signalHandler struct { - signals chan os.Signal - tty *tty + signals chan os.Signal + notifySocket *notifySocket } // forward handles the main signal event loop forwarding, resizing, or reaping depending // on the signal received. -func (h *signalHandler) forward(process *libcontainer.Process) (int, error) { +func (h *signalHandler) forward(process *libcontainer.Process, tty *tty, detach bool) (int, error) { // make sure we know the pid of our main process so that we can return // after it dies. + if detach && h.notifySocket == nil { + return 0, nil + } + pid1, err := process.Pid() if err != nil { return -1, err } - // perform the initial tty resize. - h.tty.resize() + + if h.notifySocket != nil { + if detach { + h.notifySocket.run(pid1) + return 0, nil + } else { + go h.notifySocket.run(0) + } + } + + // Perform the initial tty resize. Always ignore errors resizing because + // stdout might have disappeared (due to races with when SIGHUP is sent). + _ = tty.resize() + // Handle and forward signals. for s := range h.signals { switch s { - case syscall.SIGWINCH: - h.tty.resize() - case syscall.SIGCHLD: + case unix.SIGWINCH: + // Ignore errors resizing, as above. + _ = tty.resize() + case unix.SIGCHLD: exits, err := h.reap() if err != nil { logrus.Error(err) @@ -75,12 +96,15 @@ func (h *signalHandler) forward(process *libcontainer.Process) (int, error) { // status because we must ensure that any of the go specific process // fun such as flushing pipes are complete before we return. process.Wait() + if h.notifySocket != nil { + h.notifySocket.Close() + } return e.status, nil } } default: logrus.Debugf("sending signal to process %s", s) - if err := syscall.Kill(pid1, s.(syscall.Signal)); err != nil { + if err := unix.Kill(pid1, s.(syscall.Signal)); err != nil { logrus.Error(err) } } @@ -92,13 +116,13 @@ func (h *signalHandler) forward(process *libcontainer.Process) (int, error) { // then returns all exits to the main event loop for further processing. func (h *signalHandler) reap() (exits []exit, err error) { var ( - ws syscall.WaitStatus - rus syscall.Rusage + ws unix.WaitStatus + rus unix.Rusage ) for { - pid, err := syscall.Wait4(-1, &ws, syscall.WNOHANG, &rus) + pid, err := unix.Wait4(-1, &ws, unix.WNOHANG, &rus) if err != nil { - if err == syscall.ECHILD { + if err == unix.ECHILD { return exits, nil } return nil, err diff --git a/spec.go b/spec.go deleted file mode 100644 index 0db9475..0000000 --- a/spec.go +++ /dev/null @@ -1,166 +0,0 @@ -package main - -import ( - "encoding/json" - "fmt" - "os" - "runtime" - - "github.com/opencontainers/runtime-spec/specs-go" -) - -var ( - spec = &specs.Spec{ - Version: specs.Version, - Platform: specs.Platform{ - OS: runtime.GOOS, - Arch: runtime.GOARCH, - }, - Root: specs.Root{ - Path: "rootfs", - Readonly: true, - }, - Process: specs.Process{ - Terminal: true, - User: specs.User{}, - Args: []string{ - "sh", - }, - Env: []string{ - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", - "TERM=xterm", - }, - Cwd: "/", - NoNewPrivileges: true, - Capabilities: []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_KILL", - "CAP_AUDIT_WRITE", - }, - Rlimits: []specs.Rlimit{ - { - Type: "RLIMIT_NOFILE", - Hard: uint64(1024), - Soft: uint64(1024), - }, - }, - }, - Hostname: "ctr", - Mounts: []specs.Mount{ - { - Destination: "/proc", - Type: "proc", - Source: "proc", - Options: nil, - }, - { - Destination: "/dev", - Type: "tmpfs", - Source: "tmpfs", - Options: []string{"nosuid", "strictatime", "mode=755", "size=65536k"}, - }, - { - Destination: "/dev/pts", - Type: "devpts", - Source: "devpts", - Options: []string{"nosuid", "noexec", "newinstance", "ptmxmode=0666", "mode=0620"}, - }, - { - Destination: "/dev/shm", - Type: "tmpfs", - Source: "shm", - Options: []string{"nosuid", "noexec", "nodev", "mode=1777", "size=65536k"}, - }, - { - Destination: "/dev/mqueue", - Type: "mqueue", - Source: "mqueue", - Options: []string{"nosuid", "noexec", "nodev"}, - }, - { - Destination: "/sys", - Type: "sysfs", - Source: "sysfs", - Options: []string{"nosuid", "noexec", "nodev", "ro"}, - }, - { - Destination: "/sys/fs/cgroup", - Type: "cgroup", - Source: "cgroup", - Options: []string{"nosuid", "noexec", "nodev", "relatime"}, - }, - }, - Linux: specs.Linux{ - MaskedPaths: []string{ - "/proc/kcore", - "/proc/latency_stats", - "/proc/timer_stats", - "/proc/sched_debug", - }, - ReadonlyPaths: []string{ - "/proc/asound", - "/proc/bus", - "/proc/fs", - "/proc/irq", - "/proc/sys", - "/proc/sysrq-trigger", - }, - Resources: &specs.Resources{ - Devices: []specs.DeviceCgroup{ - { - Allow: false, - Access: sPtr("rwm"), - }, - }, - }, - Namespaces: []specs.Namespace{ - { - Type: "pid", - }, - { - Type: "ipc", - }, - { - Type: "network", - }, - { - Type: "user", - }, - { - Type: "uts", - }, - { - Type: "mount", - }, - }, - Seccomp: defaultSeccompProfile, - }, - } -) - -// loadSpec loads the specification from the provided path. -// If the path is empty then the default path will be "config.json" -func loadSpec(cPath string) (spec *specs.Spec, err error) { - cf, err := os.Open(cPath) - if err != nil { - if os.IsNotExist(err) { - return nil, fmt.Errorf("JSON specification file %s not found", cPath) - } - return nil, err - } - defer cf.Close() - - if err = json.NewDecoder(cf).Decode(&spec); err != nil { - return nil, err - } - return spec, nil -} diff --git a/tty.go b/tty.go index cd50f47..c063f76 100644 --- a/tty.go +++ b/tty.go @@ -4,16 +4,34 @@ import ( "fmt" "io" "os" + "os/signal" "sync" - "github.com/docker/docker/pkg/term" + "github.com/containerd/console" "github.com/opencontainers/runc/libcontainer" + "github.com/opencontainers/runc/libcontainer/utils" ) -// setup standard pipes so that the TTY of the calling runc process -// is not inherited by the container. -func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) { - i, err := p.InitializeIO(rootuid) +type tty struct { + epoller *console.Epoller + console *console.EpollConsole + stdin console.Console + closers []io.Closer + postStart []io.Closer + wg sync.WaitGroup + consoleC chan error +} + +func (t *tty) copyIO(w io.Writer, r io.ReadCloser) { + defer t.wg.Done() + io.Copy(w, r) + r.Close() +} + +// setup pipes for the process so that advanced features like c/r are able to easily checkpoint +// and restore the process's IO without depending on a host specific path or device +func setupProcessPipes(p *libcontainer.Process, rootuid, rootgid int) (*tty, error) { + i, err := p.InitializeIO(rootuid, rootgid) if err != nil { return nil, err } @@ -44,45 +62,66 @@ func createStdioPipes(p *libcontainer.Process, rootuid int) (*tty, error) { return t, nil } -func (t *tty) copyIO(w io.Writer, r io.ReadCloser) { - defer t.wg.Done() - io.Copy(w, r) - r.Close() +func inheritStdio(process *libcontainer.Process) error { + process.Stdin = os.Stdin + process.Stdout = os.Stdout + process.Stderr = os.Stderr + return nil } -func createTty(p *libcontainer.Process, rootuid int, consolePath string) (*tty, error) { - if consolePath != "" { - if err := p.ConsoleFromPath(consolePath); err != nil { - return nil, err - } - return &tty{}, nil - } - console, err := p.NewConsole(rootuid) +func (t *tty) recvtty(process *libcontainer.Process, socket *os.File) error { + f, err := utils.RecvFd(socket) if err != nil { - return nil, err + return err } - go io.Copy(console, os.Stdin) - go io.Copy(os.Stdout, console) + cons, err := console.ConsoleFromFile(f) + if err != nil { + return err + } + console.ClearONLCR(cons.Fd()) + epoller, err := console.NewEpoller() + if err != nil { + return err + } + epollConsole, err := epoller.Add(cons) + if err != nil { + return err + } + go epoller.Wait() + go io.Copy(epollConsole, os.Stdin) + t.wg.Add(1) + go t.copyIO(os.Stdout, epollConsole) - state, err := term.SetRawTerminal(os.Stdin.Fd()) + // set raw mode to stdin and also handle interrupt + stdin, err := console.ConsoleFromFile(os.Stdin) if err != nil { - return nil, fmt.Errorf("failed to set the terminal from the stdin: %v", err) + return err } - return &tty{ - console: console, - state: state, - closers: []io.Closer{ - console, - }, - }, nil + if err := stdin.SetRaw(); err != nil { + return fmt.Errorf("failed to set the terminal from the stdin: %v", err) + } + go handleInterrupt(stdin) + + t.epoller = epoller + t.stdin = stdin + t.console = epollConsole + t.closers = []io.Closer{epollConsole} + return nil } -type tty struct { - console libcontainer.Console - state *term.State - closers []io.Closer - postStart []io.Closer - wg sync.WaitGroup +func handleInterrupt(c console.Console) { + sigchan := make(chan os.Signal, 1) + signal.Notify(sigchan, os.Interrupt) + <-sigchan + c.Reset() + os.Exit(0) +} + +func (t *tty) waitConsole() error { + if t.consoleC != nil { + return <-t.consoleC + } + return nil } // ClosePostStart closes any fds that are provided to the container and dup2'd @@ -101,13 +140,17 @@ func (t *tty) Close() error { for _, c := range t.postStart { c.Close() } - // wait for the copy routines to finish before closing the fds + // the process is gone at this point, shutting down the console if we have + // one and wait for all IO to be finished + if t.console != nil && t.epoller != nil { + t.console.Shutdown(t.epoller.CloseConsole) + } t.wg.Wait() for _, c := range t.closers { c.Close() } - if t.state != nil { - term.RestoreTerminal(os.Stdin.Fd(), t.state) + if t.stdin != nil { + t.stdin.Reset() } return nil } @@ -116,9 +159,5 @@ func (t *tty) resize() error { if t.console == nil { return nil } - ws, err := term.GetWinsize(os.Stdin.Fd()) - if err != nil { - return err - } - return term.SetWinsize(t.console.Fd(), ws) + return t.console.ResizeFrom(console.Current()) } diff --git a/utils.go b/utils.go index 62b53b0..e8bc66b 100644 --- a/utils.go +++ b/utils.go @@ -2,74 +2,91 @@ package main import ( "fmt" + "net" "os" + "os/exec" "path/filepath" - "syscall" + "strconv" - "github.com/Sirupsen/logrus" "github.com/coreos/go-systemd/activation" "github.com/opencontainers/runc/libcontainer" "github.com/opencontainers/runc/libcontainer/cgroups/systemd" "github.com/opencontainers/runc/libcontainer/configs" "github.com/opencontainers/runc/libcontainer/specconv" - "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/runc/libcontainer/utils" + specs "github.com/opencontainers/runtime-spec/specs-go" + "github.com/sirupsen/logrus" + "golang.org/x/sys/unix" ) // startContainer starts the container. Returns the exit status or -1 and an // error. Signals sent to the current process will be forwarded to container. -func startContainer(spec *specs.Spec, id, pidFile string, detach, useSystemdCgroup bool) (int, error) { - // create the libcontainer config +func startContainer(spec *specs.Spec, id, pidFile, consoleSocket, root string, detach bool) (int, error) { + notifySocket := newNotifySocket(id, root) + if notifySocket != nil { + // Setup the spec for the notify socket. + notifySocket.setupSpec(spec) + } + + // Create the libcontainer config. + useSystemdCgroup := false config, err := specconv.CreateLibcontainerConfig(&specconv.CreateOpts{ CgroupName: id, UseSystemdCgroup: useSystemdCgroup, NoPivotRoot: false, + NoNewKeyring: false, Spec: spec, + Rootless: true, }) if err != nil { return -1, err } - if _, err := os.Stat(config.Rootfs); err != nil { - if os.IsNotExist(err) { - return -1, fmt.Errorf("rootfs (%q) does not exist", config.Rootfs) - } - return -1, err - } - - factory, err := loadFactory(useSystemdCgroup) + // Load the factory. + factory, err := loadFactory(root, useSystemdCgroup) if err != nil { return -1, err } + // Create the factory. container, err := factory.Create(id, config) if err != nil { return -1, err } - // Support on-demand socket activation by passing file descriptors into the container init process. + if notifySocket != nil { + // Setup the socket for the notify socket. + err := notifySocket.setupSocket() + if err != nil { + return -1, err + } + } + + // Support on-demand socket activation by passing file descriptors into + // the container init process. listenFDs := []*os.File{} if os.Getenv("LISTEN_FDS") != "" { listenFDs = activation.Files(false) } + // Initialize the runner. r := &runner{ enableSubreaper: true, shouldDestroy: true, container: container, - console: console, + listenFDs: listenFDs, + notifySocket: notifySocket, + consoleSocket: consoleSocket, detach: detach, pidFile: pidFile, - listenFDs: listenFDs, } - return r.run(&spec.Process) + // Run the process. + return r.run(spec.Process) } // loadFactory returns the configured factory instance for execing containers. -func loadFactory(useSystemdCgroup bool) (libcontainer.Factory, error) { - abs, err := filepath.Abs(root) - if err != nil { - return nil, err - } +func loadFactory(root string, useSystemdCgroup bool) (libcontainer.Factory, error) { + // Setup the cgroups manager. Default is cgroupfs. cgroupManager := libcontainer.Cgroupfs if useSystemdCgroup { if systemd.UseSystemd() { @@ -78,25 +95,61 @@ func loadFactory(useSystemdCgroup bool) (libcontainer.Factory, error) { return nil, fmt.Errorf("systemd cgroup flag passed, but systemd support for managing cgroups is not available") } } - return libcontainer.New(abs, cgroupManager, func(l *libcontainer.LinuxFactory) error { - return nil - }) + + // We resolve the paths for {newuidmap,newgidmap} from the context of runc, + // to avoid doing a path lookup in the nsexec context. TODO: The binary + // names are not currently configurable. + newuidmap, err := exec.LookPath("newuidmap") + if err != nil { + newuidmap = "" + } + newgidmap, err := exec.LookPath("newgidmap") + if err != nil { + newgidmap = "" + } + + // Create the new libcontainer factory. + return libcontainer.New(root, cgroupManager, nil, nil, + libcontainer.NewuidmapPath(newuidmap), + libcontainer.NewgidmapPath(newgidmap)) } // newProcess returns a new libcontainer Process with the arguments from the // spec and stdio from the current process. func newProcess(p specs.Process) (*libcontainer.Process, error) { + // Create the libcontainer process. lp := &libcontainer.Process{ - Args: p.Args, - Env: p.Env, - // TODO: fix libcontainer's API to better support uid/gid in a typesafe way. + Args: p.Args, + Env: p.Env, User: fmt.Sprintf("%d:%d", p.User.UID, p.User.GID), Cwd: p.Cwd, - Capabilities: p.Capabilities, Label: p.SelinuxLabel, NoNewPrivileges: &p.NoNewPrivileges, AppArmorProfile: p.ApparmorProfile, } + + // Setup the console size. + if p.ConsoleSize != nil { + lp.ConsoleWidth = uint16(p.ConsoleSize.Width) + lp.ConsoleHeight = uint16(p.ConsoleSize.Height) + } + + // Convert the capabilities. + if p.Capabilities != nil { + lp.Capabilities = &configs.Capabilities{} + lp.Capabilities.Bounding = p.Capabilities.Bounding + lp.Capabilities.Effective = p.Capabilities.Effective + lp.Capabilities.Inheritable = p.Capabilities.Inheritable + lp.Capabilities.Permitted = p.Capabilities.Permitted + lp.Capabilities.Ambient = p.Capabilities.Ambient + } + + // Setup the additional user groups. + for _, gid := range p.User.AdditionalGids { + lp.AdditionalGroups = append(lp.AdditionalGroups, strconv.FormatUint(uint64(gid), 10)) + } + + // Setup the Rlimits. for _, rlimit := range p.Rlimits { rl, err := createLibContainerRlimit(rlimit) if err != nil { @@ -104,23 +157,8 @@ func newProcess(p specs.Process) (*libcontainer.Process, error) { } lp.Rlimits = append(lp.Rlimits, rl) } - return lp, nil -} -func dupStdio(process *libcontainer.Process, rootuid int) error { - process.Stdin = os.Stdin - process.Stdout = os.Stdout - process.Stderr = os.Stderr - for _, fd := range []uintptr{ - os.Stdin.Fd(), - os.Stdout.Fd(), - os.Stderr.Fd(), - } { - if err := syscall.Fchown(int(fd), rootuid, rootuid); err != nil { - return err - } - } - return nil + return lp, nil } func destroy(container libcontainer.Container) { @@ -129,24 +167,55 @@ func destroy(container libcontainer.Container) { } } -// setupIO sets the proper IO on the process depending on the configuration -// If there is a nil error then there must be a non nil tty returned -func setupIO(process *libcontainer.Process, rootuid int, console string, createTTY, detach bool) (*tty, error) { - // detach and createTty will not work unless a console path is passed - // so error out here before changing any terminal settings - if createTTY && detach && console == "" { - return nil, fmt.Errorf("cannot allocate tty if runc will detach") - } +func setupIO(process *libcontainer.Process, rootuid, rootgid int, createTTY, detach bool, sockpath string) (*tty, error) { if createTTY { - return createTty(process, rootuid, console) + process.Stdin = nil + process.Stdout = nil + process.Stderr = nil + t := &tty{} + if !detach { + parent, child, err := utils.NewSockPair("console") + if err != nil { + return nil, err + } + process.ConsoleSocket = child + t.postStart = append(t.postStart, parent, child) + t.consoleC = make(chan error, 1) + go func() { + if err := t.recvtty(process, parent); err != nil { + t.consoleC <- err + } + t.consoleC <- nil + }() + } else { + // the caller of runc will handle receiving the console master + conn, err := net.Dial("unix", sockpath) + if err != nil { + return nil, err + } + uc, ok := conn.(*net.UnixConn) + if !ok { + return nil, fmt.Errorf("casting to UnixConn failed") + } + t.postStart = append(t.postStart, uc) + socket, err := uc.File() + if err != nil { + return nil, err + } + t.postStart = append(t.postStart, socket) + process.ConsoleSocket = socket + } + return t, nil } + // when runc will detach the caller provides the stdio to runc via runc's 0,1,2 + // and the container's process inherits runc's stdio. if detach { - if err := dupStdio(process, rootuid); err != nil { + if err := inheritStdio(process); err != nil { return nil, err } return &tty{}, nil } - return createStdioPipes(process, rootuid) + return setupProcessPipes(process, rootuid, rootgid) } // createPidFile creates a file with the processes pid inside it atomically @@ -175,46 +244,86 @@ func createPidFile(path string, process *libcontainer.Process) error { type runner struct { enableSubreaper bool - shouldDestroy bool detach bool - listenFDs []*os.File + shouldDestroy bool + consoleSocket string pidFile string - console string container libcontainer.Container + listenFDs []*os.File + notifySocket *notifySocket } func (r *runner) run(config *specs.Process) (int, error) { + // Check the terminal settings. + if r.detach && config.Terminal && r.consoleSocket == "" { + return -1, fmt.Errorf("cannot allocate tty if runc will detach without setting console socket") + } + if (!r.detach || !config.Terminal) && r.consoleSocket != "" { + return -1, fmt.Errorf("cannot use console socket if runc will not detach or allocate tty") + } + + // Create the process. process, err := newProcess(*config) if err != nil { r.destroy() return -1, err } + + // Setup the listen file descriptors. if len(r.listenFDs) > 0 { process.Env = append(process.Env, fmt.Sprintf("LISTEN_FDS=%d", len(r.listenFDs)), "LISTEN_PID=1") process.ExtraFiles = append(process.ExtraFiles, r.listenFDs...) } - rootuid, err := r.container.Config().HostUID() + + // Get the rootuid. + rootuid, err := r.container.Config().HostRootUID() if err != nil { r.destroy() return -1, err } - tty, err := setupIO(process, rootuid, r.console, config.Terminal, r.detach) + + // Get the rootgid. + rootgid, err := r.container.Config().HostRootGID() if err != nil { r.destroy() return -1, err } - handler := newSignalHandler(tty, r.enableSubreaper) - if err := r.container.Start(process); err != nil { + + // Setting up IO is a two stage process. We need to modify process to deal + // with detaching containers, and then we get a tty after the container has + // started. + handler := newSignalHandler(r.enableSubreaper, r.notifySocket) + tty, err := setupIO(process, rootuid, rootgid, config.Terminal, r.detach, r.consoleSocket) + if err != nil { + r.destroy() + return -1, err + } + defer tty.Close() + + // Run the container. + if err := r.container.Run(process); err != nil { r.destroy() tty.Close() return -1, err } - if err := tty.ClosePostStart(); err != nil { + + // Wait for the tty. + if err := tty.waitConsole(); err != nil { r.terminate(process) r.destroy() tty.Close() return -1, err } + + // Close after start the tty. + if err = tty.ClosePostStart(); err != nil { + r.terminate(process) + r.destroy() + tty.Close() + return -1, err + } + + // Create the pid file. if r.pidFile != "" { if err := createPidFile(r.pidFile, process); err != nil { r.terminate(process) @@ -223,16 +332,21 @@ func (r *runner) run(config *specs.Process) (int, error) { return -1, err } } - if r.detach { - tty.Close() - return 0, nil - } - status, err := handler.forward(process) + + // Forward the handler. + status, err := handler.forward(process, tty, detach) if err != nil { r.terminate(process) } + + // Return early if we are detaching. + if r.detach { + return 0, nil + } + + // Cleanup. r.destroy() - tty.Close() + return status, err } @@ -243,27 +357,18 @@ func (r *runner) destroy() { } func (r *runner) terminate(p *libcontainer.Process) { - p.Signal(syscall.SIGKILL) - p.Wait() + _ = p.Signal(unix.SIGKILL) + _, _ = p.Wait() } -func sPtr(s string) *string { return &s } - -func createLibContainerRlimit(rlimit specs.Rlimit) (configs.Rlimit, error) { +func createLibContainerRlimit(rlimit specs.POSIXRlimit) (configs.Rlimit, error) { rl, err := strToRlimit(rlimit.Type) if err != nil { return configs.Rlimit{}, err } return configs.Rlimit{ Type: rl, - Hard: uint64(rlimit.Hard), - Soft: uint64(rlimit.Soft), + Hard: rlimit.Hard, + Soft: rlimit.Soft, }, nil } - -// If systemd is supporting sd_notify protocol, this function will add support -// for sd_notify protocol from within the container. -func setupSdNotify(spec *specs.Spec, notifySocket string) { - spec.Mounts = append(spec.Mounts, specs.Mount{Destination: notifySocket, Type: "bind", Source: notifySocket, Options: []string{"bind"}}) - spec.Process.Env = append(spec.Process.Env, fmt.Sprintf("NOTIFY_SOCKET=%s", notifySocket)) -}