Przeglądaj źródła

Update libcontainer to aac9179bbadbf958054ce97ab36

Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
Michael Crosby 9 lat temu
rodzic
commit
189d2c7985

+ 1 - 1
hack/vendor.sh

@@ -42,7 +42,7 @@ clone git github.com/endophage/gotuf 9bcdad0308e34a49f38448b8ad436ad8860825ce
 clone git github.com/jfrazelle/go 6e461eb70cb4187b41a84e9a567d7137bdbe0f16
 clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
 
-clone git github.com/opencontainers/runc 08b5415ffa3769ff7c1d2f673f61382d69aabb7d # libcontainer
+clone git github.com/opencontainers/runc aac9179bbadbf958054ce97ab368ac178140e5da # libcontainer
 # libcontainer deps (see src/github.com/docker/libcontainer/update-vendor.sh)
 clone git github.com/coreos/go-systemd v3
 clone git github.com/godbus/dbus v2

+ 11 - 3
vendor/src/github.com/opencontainers/runc/libcontainer/configs/config.go

@@ -20,8 +20,12 @@ type IDMap struct {
 }
 
 // Seccomp represents syscall restrictions
+// By default, only the native architecture of the kernel is allowed to be used
+// for syscalls. Additional architectures can be added by specifying them in
+// Architectures.
 type Seccomp struct {
 	DefaultAction Action     `json:"default_action"`
+	Architectures []string   `json:"architectures"`
 	Syscalls      []*Syscall `json:"syscalls"`
 }
 
@@ -169,6 +173,9 @@ type Config struct {
 	// Hooks are a collection of actions to perform at various container lifecycle events.
 	// Hooks are not able to be marshaled to json but they are also not needed to.
 	Hooks *Hooks `json:"-"`
+
+	// Version is the version of opencontainer specification that is supported.
+	Version string `json:"version"`
 }
 
 type Hooks struct {
@@ -182,9 +189,10 @@ type Hooks struct {
 
 // HookState is the payload provided to a hook on execution.
 type HookState struct {
-	ID   string `json:"id"`
-	Pid  int    `json:"pid"`
-	Root string `json:"root"`
+	Version string `json:"version"`
+	ID      string `json:"id"`
+	Pid     int    `json:"pid"`
+	Root    string `json:"root"`
 }
 
 type Hook interface {

+ 0 - 45
vendor/src/github.com/opencontainers/runc/libcontainer/configs/mount.go

@@ -1,13 +1,5 @@
 package configs
 
-import (
-	"path/filepath"
-	"strings"
-	"syscall"
-
-	"github.com/opencontainers/runc/libcontainer/label"
-)
-
 type Mount struct {
 	// Source path for the mount.
 	Source string `json:"source"`
@@ -36,40 +28,3 @@ type Mount struct {
 	// Optional Command to be run after Source is mounted.
 	PostmountCmds []Command `json:"postmount_cmds"`
 }
-
-func (m *Mount) Remount(rootfs string) error {
-	var (
-		dest = m.Destination
-	)
-	if !strings.HasPrefix(dest, rootfs) {
-		dest = filepath.Join(rootfs, dest)
-	}
-
-	if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil {
-		return err
-	}
-	return nil
-}
-
-// Do the mount operation followed by additional mounts required to take care
-// of propagation flags.
-func (m *Mount) MountPropagate(rootfs string, mountLabel string) error {
-	var (
-		dest = m.Destination
-		data = label.FormatMountLabel(m.Data, mountLabel)
-	)
-	if !strings.HasPrefix(dest, rootfs) {
-		dest = filepath.Join(rootfs, dest)
-	}
-
-	if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
-		return err
-	}
-
-	for _, pflag := range m.PropagationFlags {
-		if err := syscall.Mount("", dest, "", uintptr(pflag), ""); err != nil {
-			return err
-		}
-	}
-	return nil
-}

+ 1 - 1
vendor/src/github.com/opencontainers/runc/libcontainer/console_linux.go

@@ -75,7 +75,7 @@ func (c *linuxConsole) Close() error {
 
 // mount initializes the console inside the rootfs mounting with the specified mount label
 // and applying the correct ownership of the console.
-func (c *linuxConsole) mount(rootfs, mountLabel string, uid, gid int) error {
+func (c *linuxConsole) mount(rootfs, mountLabel string) error {
 	oldMask := syscall.Umask(0000)
 	defer syscall.Umask(oldMask)
 	if err := label.SetFileLabel(c.slavePath, mountLabel); err != nil {

+ 3 - 2
vendor/src/github.com/opencontainers/runc/libcontainer/container_linux.go

@@ -250,8 +250,9 @@ func (c *linuxContainer) Destroy() error {
 	c.initProcess = nil
 	if c.config.Hooks != nil {
 		s := configs.HookState{
-			ID:   c.id,
-			Root: c.config.Rootfs,
+			Version: c.config.Version,
+			ID:      c.id,
+			Root:    c.config.Rootfs,
 		}
 		for _, hook := range c.config.Hooks.Poststop {
 			if err := hook.Run(s); err != nil {

+ 32 - 10
vendor/src/github.com/opencontainers/runc/libcontainer/init_linux.go

@@ -187,16 +187,10 @@ func setupUser(config *initConfig) error {
 			return err
 		}
 	}
-	// change the permissions on the STDIO of the current process so that when the user
-	// is changed for the container, it's STDIO of the process matches the user.
-	for _, fd := range []uintptr{
-		os.Stdin.Fd(),
-		os.Stderr.Fd(),
-		os.Stdout.Fd(),
-	} {
-		if err := syscall.Fchown(int(fd), execUser.Uid, execUser.Gid); err != nil {
-			return err
-		}
+	// before we change to the container's user make sure that the processes STDIO
+	// is correctly owned by the user that we are switching to.
+	if err := fixStdioPermissions(execUser); err != nil {
+		return err
 	}
 	suppGroups := append(execUser.Sgids, addGroups...)
 	if err := syscall.Setgroups(suppGroups); err != nil {
@@ -218,6 +212,34 @@ func setupUser(config *initConfig) error {
 	return nil
 }
 
+// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user.
+// The ownership needs to match because it is created outside of the container and needs to be
+// localized.
+func fixStdioPermissions(u *user.ExecUser) error {
+	var null syscall.Stat_t
+	if err := syscall.Stat("/dev/null", &null); err != nil {
+		return err
+	}
+	for _, fd := range []uintptr{
+		os.Stdin.Fd(),
+		os.Stderr.Fd(),
+		os.Stdout.Fd(),
+	} {
+		var s syscall.Stat_t
+		if err := syscall.Fstat(int(fd), &s); err != nil {
+			return err
+		}
+		// skip chown of /dev/null if it was used as one of the STDIO fds.
+		if s.Rdev == null.Rdev {
+			continue
+		}
+		if err := syscall.Fchown(int(fd), u.Uid, u.Gid); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
 // setupNetwork sets up and initializes any network interface inside the container.
 func setupNetwork(config *initConfig) error {
 	for _, config := range config.Networks {

+ 19 - 3
vendor/src/github.com/opencontainers/runc/libcontainer/nsenter/nsexec.c

@@ -65,11 +65,11 @@ static int clone_parent(jmp_buf * env)
 
 void nsexec()
 {
-	char *namespaces[] = { "ipc", "uts", "net", "pid", "mnt" };
+	char *namespaces[] = { "ipc", "uts", "net", "pid", "mnt", "user" };
 	const int num = sizeof(namespaces) / sizeof(char *);
 	jmp_buf env;
 	char buf[PATH_MAX], *val;
-	int i, tfd, child, len, pipenum, consolefd = -1;
+	int i, tfd, self_tfd, child, len, pipenum, consolefd = -1;
 	pid_t pid;
 	char *console;
 
@@ -114,17 +114,30 @@ void nsexec()
 		exit(1);
 	}
 
+	self_tfd = open("/proc/self/ns", O_DIRECTORY | O_RDONLY);
+	if (self_tfd == -1) {
+		pr_perror("Failed to open /proc/self/ns");
+		exit(1);
+	}
+
 	for (i = 0; i < num; i++) {
 		struct stat st;
+		struct stat self_st;
 		int fd;
 
 		/* Symlinks on all namespaces exist for dead processes, but they can't be opened */
-		if (fstatat(tfd, namespaces[i], &st, AT_SYMLINK_NOFOLLOW) == -1) {
+		if (fstatat(tfd, namespaces[i], &st, 0) == -1) {
 			// Ignore nonexistent namespaces.
 			if (errno == ENOENT)
 				continue;
 		}
 
+		/* Skip namespaces we're already part of */
+		if (fstatat(self_tfd, namespaces[i], &self_st, 0) != -1 &&
+		    st.st_ino == self_st.st_ino) {
+			continue;
+		}
+
 		fd = openat(tfd, namespaces[i], O_RDONLY);
 		if (fd == -1) {
 			pr_perror("Failed to open ns file %s for ns %s", buf,
@@ -139,6 +152,9 @@ void nsexec()
 		close(fd);
 	}
 
+	close(self_tfd);
+	close(tfd);
+
 	if (setjmp(env) == 1) {
 		// Child
 

+ 4 - 3
vendor/src/github.com/opencontainers/runc/libcontainer/process_linux.go

@@ -203,9 +203,10 @@ func (p *initProcess) start() (err error) {
 	}()
 	if p.config.Config.Hooks != nil {
 		s := configs.HookState{
-			ID:   p.container.id,
-			Pid:  p.pid(),
-			Root: p.config.Config.Rootfs,
+			Version: p.container.config.Version,
+			ID:      p.container.id,
+			Pid:     p.pid(),
+			Root:    p.config.Config.Rootfs,
 		}
 		for _, hook := range p.config.Config.Hooks.Prestart {
 			if err := hook.Run(s); err != nil {

+ 50 - 11
vendor/src/github.com/opencontainers/runc/libcontainer/rootfs_linux.go

@@ -68,7 +68,7 @@ func setupRootfs(config *configs.Config, console *linuxConsole) (err error) {
 		return newSystemError(err)
 	}
 	if !setupDev {
-		if err := reOpenDevNull(config.Rootfs); err != nil {
+		if err := reOpenDevNull(); err != nil {
 			return newSystemError(err)
 		}
 	}
@@ -106,12 +106,12 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
 		if err := os.MkdirAll(dest, 0755); err != nil {
 			return err
 		}
-		return m.MountPropagate(rootfs, mountLabel)
+		return mountPropagate(m, rootfs, mountLabel)
 	case "mqueue":
 		if err := os.MkdirAll(dest, 0755); err != nil {
 			return err
 		}
-		if err := m.MountPropagate(rootfs, mountLabel); err != nil {
+		if err := mountPropagate(m, rootfs, mountLabel); err != nil {
 			return err
 		}
 		return label.SetFileLabel(dest, mountLabel)
@@ -122,7 +122,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
 				return err
 			}
 		}
-		if err := m.MountPropagate(rootfs, mountLabel); err != nil {
+		if err := mountPropagate(m, rootfs, mountLabel); err != nil {
 			return err
 		}
 		if stat != nil {
@@ -135,12 +135,12 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
 		if err := os.MkdirAll(dest, 0755); err != nil {
 			return err
 		}
-		return m.MountPropagate(rootfs, mountLabel)
+		return mountPropagate(m, rootfs, mountLabel)
 	case "securityfs":
 		if err := os.MkdirAll(dest, 0755); err != nil {
 			return err
 		}
-		return m.MountPropagate(rootfs, mountLabel)
+		return mountPropagate(m, rootfs, mountLabel)
 	case "bind":
 		stat, err := os.Stat(m.Source)
 		if err != nil {
@@ -158,14 +158,16 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
 		if err := checkMountDestination(rootfs, dest); err != nil {
 			return err
 		}
+		// update the mount with the correct dest after symlinks are resolved.
+		m.Destination = dest
 		if err := createIfNotExists(dest, stat.IsDir()); err != nil {
 			return err
 		}
-		if err := m.MountPropagate(rootfs, mountLabel); err != nil {
+		if err := mountPropagate(m, rootfs, mountLabel); err != nil {
 			return err
 		}
 		// bind mount won't change mount options, we need remount to make mount options effective.
-		if err := m.Remount(rootfs); err != nil {
+		if err := remount(m, rootfs); err != nil {
 			return err
 		}
 		if m.Relabel != "" {
@@ -234,7 +236,7 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error {
 				Destination: m.Destination,
 				Flags:       defaultMountFlags | syscall.MS_RDONLY,
 			}
-			if err := mcgrouproot.Remount(rootfs); err != nil {
+			if err := remount(mcgrouproot, rootfs); err != nil {
 				return err
 			}
 		}
@@ -328,7 +330,7 @@ func setupDevSymlinks(rootfs string) error {
 // this method will make them point to `/dev/null` in this container's rootfs.  This
 // needs to be called after we chroot/pivot into the container's rootfs so that any
 // symlinks are resolved locally.
-func reOpenDevNull(rootfs string) error {
+func reOpenDevNull() error {
 	var stat, devNullStat syscall.Stat_t
 	file, err := os.Open("/dev/null")
 	if err != nil {
@@ -433,7 +435,7 @@ func setupPtmx(config *configs.Config, console *linuxConsole) error {
 		return fmt.Errorf("symlink dev ptmx %s", err)
 	}
 	if console != nil {
-		return console.mount(config.Rootfs, config.MountLabel, 0, 0)
+		return console.mount(config.Rootfs, config.MountLabel)
 	}
 	return nil
 }
@@ -532,3 +534,40 @@ func writeSystemProperty(key, value string) error {
 	keyPath := strings.Replace(key, ".", "/", -1)
 	return ioutil.WriteFile(path.Join("/proc/sys", keyPath), []byte(value), 0644)
 }
+
+func remount(m *configs.Mount, rootfs string) error {
+	var (
+		dest = m.Destination
+	)
+	if !strings.HasPrefix(dest, rootfs) {
+		dest = filepath.Join(rootfs, dest)
+	}
+
+	if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags|syscall.MS_REMOUNT), ""); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Do the mount operation followed by additional mounts required to take care
+// of propagation flags.
+func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error {
+	var (
+		dest = m.Destination
+		data = label.FormatMountLabel(m.Data, mountLabel)
+	)
+	if !strings.HasPrefix(dest, rootfs) {
+		dest = filepath.Join(rootfs, dest)
+	}
+
+	if err := syscall.Mount(m.Source, dest, m.Device, uintptr(m.Flags), data); err != nil {
+		return err
+	}
+
+	for _, pflag := range m.PropagationFlags {
+		if err := syscall.Mount("", dest, "", uintptr(pflag), ""); err != nil {
+			return err
+		}
+	}
+	return nil
+}

+ 12 - 0
vendor/src/github.com/opencontainers/runc/libcontainer/seccomp/seccomp_linux.go

@@ -37,6 +37,18 @@ func InitSeccomp(config *configs.Seccomp) error {
 		return fmt.Errorf("error creating filter: %s", err)
 	}
 
+	// Add extra architectures
+	for _, arch := range config.Architectures {
+		scmpArch, err := libseccomp.GetArchFromString(arch)
+		if err != nil {
+			return err
+		}
+
+		if err := filter.AddArch(scmpArch); err != nil {
+			return err
+		}
+	}
+
 	// Unset no new privs bit
 	if err := filter.SetNoNewPrivsBit(false); err != nil {
 		return fmt.Errorf("error setting no new privileges: %s", err)