Bläddra i källkod

vendor: github.com/opencontainers/runc v1.0.1

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
Akihiro Suda 4 år sedan
förälder
incheckning
1256aa0241

+ 1 - 1
vendor.conf

@@ -87,7 +87,7 @@ google.golang.org/grpc                              f495f5b15ae7ccda3b38c53a1bfc
 # the containerd project first, and update both after that is merged.
 # the containerd project first, and update both after that is merged.
 # This commit does not need to match RUNC_COMMIT as it is used for helper
 # This commit does not need to match RUNC_COMMIT as it is used for helper
 # packages but should be newer or equal.
 # packages but should be newer or equal.
-github.com/opencontainers/runc                      b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7 # v1.0.0-rc95
+github.com/opencontainers/runc                      4144b63817ebcc5b358fc2c8ef95f7cddd709aa7 # v1.0.1
 github.com/opencontainers/runtime-spec              1c3f411f041711bbeecf35ff7e93461ea6789220 # v1.0.3-0.20210326190908-1c3f411f0417
 github.com/opencontainers/runtime-spec              1c3f411f041711bbeecf35ff7e93461ea6789220 # v1.0.3-0.20210326190908-1c3f411f0417
 github.com/opencontainers/image-spec                d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
 github.com/opencontainers/image-spec                d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
 github.com/cyphar/filepath-securejoin               a261ee33d7a517f054effbf451841abaafe3e0fd # v0.2.2
 github.com/cyphar/filepath-securejoin               a261ee33d7a517f054effbf451841abaafe3e0fd # v0.2.2

+ 6 - 6
vendor/github.com/opencontainers/runc/go.mod

@@ -3,26 +3,26 @@ module github.com/opencontainers/runc
 go 1.13
 go 1.13
 
 
 require (
 require (
+	github.com/bits-and-blooms/bitset v1.2.0
 	github.com/checkpoint-restore/go-criu/v5 v5.0.0
 	github.com/checkpoint-restore/go-criu/v5 v5.0.0
-	github.com/cilium/ebpf v0.5.0
+	github.com/cilium/ebpf v0.6.2
 	github.com/containerd/console v1.0.2
 	github.com/containerd/console v1.0.2
-	github.com/coreos/go-systemd/v22 v22.3.1
+	github.com/coreos/go-systemd/v22 v22.3.2
 	github.com/cyphar/filepath-securejoin v0.2.2
 	github.com/cyphar/filepath-securejoin v0.2.2
 	github.com/docker/go-units v0.4.0
 	github.com/docker/go-units v0.4.0
 	github.com/godbus/dbus/v5 v5.0.4
 	github.com/godbus/dbus/v5 v5.0.4
 	github.com/moby/sys/mountinfo v0.4.1
 	github.com/moby/sys/mountinfo v0.4.1
 	github.com/mrunalp/fileutils v0.5.0
 	github.com/mrunalp/fileutils v0.5.0
 	github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
 	github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417
-	github.com/opencontainers/selinux v1.8.0
+	github.com/opencontainers/selinux v1.8.2
 	github.com/pkg/errors v0.9.1
 	github.com/pkg/errors v0.9.1
 	github.com/seccomp/libseccomp-golang v0.9.1
 	github.com/seccomp/libseccomp-golang v0.9.1
-	github.com/sirupsen/logrus v1.7.0
+	github.com/sirupsen/logrus v1.8.1
 	github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
 	github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
 	// NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
 	// NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
 	github.com/urfave/cli v1.22.1
 	github.com/urfave/cli v1.22.1
 	github.com/vishvananda/netlink v1.1.0
 	github.com/vishvananda/netlink v1.1.0
-	github.com/willf/bitset v1.1.11
 	golang.org/x/net v0.0.0-20201224014010-6772e930b67b
 	golang.org/x/net v0.0.0-20201224014010-6772e930b67b
 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887
 	golang.org/x/sys v0.0.0-20210426230700-d19ff857e887
-	google.golang.org/protobuf v1.25.0
+	google.golang.org/protobuf v1.26.0
 )
 )

+ 53 - 7
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/open.go → vendor/github.com/opencontainers/runc/libcontainer/cgroups/file.go

@@ -1,6 +1,7 @@
-package fscommon
+package cgroups
 
 
 import (
 import (
+	"bytes"
 	"os"
 	"os"
 	"strings"
 	"strings"
 	"sync"
 	"sync"
@@ -10,6 +11,54 @@ import (
 	"golang.org/x/sys/unix"
 	"golang.org/x/sys/unix"
 )
 )
 
 
+// OpenFile opens a cgroup file in a given dir with given flags.
+// It is supposed to be used for cgroup files only.
+func OpenFile(dir, file string, flags int) (*os.File, error) {
+	if dir == "" {
+		return nil, errors.Errorf("no directory specified for %s", file)
+	}
+	return openFile(dir, file, flags)
+}
+
+// ReadFile reads data from a cgroup file in dir.
+// It is supposed to be used for cgroup files only.
+func ReadFile(dir, file string) (string, error) {
+	fd, err := OpenFile(dir, file, unix.O_RDONLY)
+	if err != nil {
+		return "", err
+	}
+	defer fd.Close()
+	var buf bytes.Buffer
+
+	_, err = buf.ReadFrom(fd)
+	return buf.String(), err
+}
+
+// WriteFile writes data to a cgroup file in dir.
+// It is supposed to be used for cgroup files only.
+func WriteFile(dir, file, data string) error {
+	fd, err := OpenFile(dir, file, unix.O_WRONLY)
+	if err != nil {
+		return err
+	}
+	defer fd.Close()
+	if err := retryingWriteFile(fd, data); err != nil {
+		return errors.Wrapf(err, "failed to write %q", data)
+	}
+	return nil
+}
+
+func retryingWriteFile(fd *os.File, data string) error {
+	for {
+		_, err := fd.Write([]byte(data))
+		if errors.Is(err, unix.EINTR) {
+			logrus.Infof("interrupted while writing %s to %s", data, fd.Name())
+			continue
+		}
+		return err
+	}
+}
+
 const (
 const (
 	cgroupfsDir    = "/sys/fs/cgroup"
 	cgroupfsDir    = "/sys/fs/cgroup"
 	cgroupfsPrefix = cgroupfsDir + "/"
 	cgroupfsPrefix = cgroupfsDir + "/"
@@ -28,7 +77,8 @@ var (
 func prepareOpenat2() error {
 func prepareOpenat2() error {
 	prepOnce.Do(func() {
 	prepOnce.Do(func() {
 		fd, err := unix.Openat2(-1, cgroupfsDir, &unix.OpenHow{
 		fd, err := unix.Openat2(-1, cgroupfsDir, &unix.OpenHow{
-			Flags: unix.O_DIRECTORY | unix.O_PATH})
+			Flags: unix.O_DIRECTORY | unix.O_PATH,
+		})
 		if err != nil {
 		if err != nil {
 			prepErr = &os.PathError{Op: "openat2", Path: cgroupfsDir, Err: err}
 			prepErr = &os.PathError{Op: "openat2", Path: cgroupfsDir, Err: err}
 			if err != unix.ENOSYS {
 			if err != unix.ENOSYS {
@@ -52,7 +102,6 @@ func prepareOpenat2() error {
 			// cgroupv2 has a single mountpoint and no "cpu,cpuacct" symlinks
 			// cgroupv2 has a single mountpoint and no "cpu,cpuacct" symlinks
 			resolveFlags |= unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_SYMLINKS
 			resolveFlags |= unix.RESOLVE_NO_XDEV | unix.RESOLVE_NO_SYMLINKS
 		}
 		}
-
 	})
 	})
 
 
 	return prepErr
 	return prepErr
@@ -60,10 +109,7 @@ func prepareOpenat2() error {
 
 
 // OpenFile opens a cgroup file in a given dir with given flags.
 // OpenFile opens a cgroup file in a given dir with given flags.
 // It is supposed to be used for cgroup files only.
 // It is supposed to be used for cgroup files only.
-func OpenFile(dir, file string, flags int) (*os.File, error) {
-	if dir == "" {
-		return nil, errors.Errorf("no directory specified for %s", file)
-	}
+func openFile(dir, file string, flags int) (*os.File, error) {
 	mode := os.FileMode(0)
 	mode := os.FileMode(0)
 	if TestMode && flags&os.O_WRONLY != 0 {
 	if TestMode && flags&os.O_WRONLY != 0 {
 		// "emulate" cgroup fs for unit tests
 		// "emulate" cgroup fs for unit tests

+ 0 - 51
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/fscommon.go

@@ -1,51 +0,0 @@
-// +build linux
-
-package fscommon
-
-import (
-	"bytes"
-	"os"
-
-	"github.com/pkg/errors"
-	"github.com/sirupsen/logrus"
-	"golang.org/x/sys/unix"
-)
-
-// WriteFile writes data to a cgroup file in dir.
-// It is supposed to be used for cgroup files only.
-func WriteFile(dir, file, data string) error {
-	fd, err := OpenFile(dir, file, unix.O_WRONLY)
-	if err != nil {
-		return err
-	}
-	defer fd.Close()
-	if err := retryingWriteFile(fd, data); err != nil {
-		return errors.Wrapf(err, "failed to write %q", data)
-	}
-	return nil
-}
-
-// ReadFile reads data from a cgroup file in dir.
-// It is supposed to be used for cgroup files only.
-func ReadFile(dir, file string) (string, error) {
-	fd, err := OpenFile(dir, file, unix.O_RDONLY)
-	if err != nil {
-		return "", err
-	}
-	defer fd.Close()
-	var buf bytes.Buffer
-
-	_, err = buf.ReadFrom(fd)
-	return buf.String(), err
-}
-
-func retryingWriteFile(fd *os.File, data string) error {
-	for {
-		_, err := fd.Write([]byte(data))
-		if errors.Is(err, unix.EINTR) {
-			logrus.Infof("interrupted while writing %s to %s", data, fd.Name())
-			continue
-		}
-		return err
-	}
-}

+ 0 - 122
vendor/github.com/opencontainers/runc/libcontainer/cgroups/fscommon/utils.go

@@ -1,122 +0,0 @@
-// +build linux
-
-package fscommon
-
-import (
-	"errors"
-	"fmt"
-	"math"
-	"strconv"
-	"strings"
-)
-
-var (
-	ErrNotValidFormat = errors.New("line is not a valid key value format")
-)
-
-// ParseUint converts a string to an uint64 integer.
-// Negative values are returned at zero as, due to kernel bugs,
-// some of the memory cgroup stats can be negative.
-func ParseUint(s string, base, bitSize int) (uint64, error) {
-	value, err := strconv.ParseUint(s, base, bitSize)
-	if err != nil {
-		intValue, intErr := strconv.ParseInt(s, base, bitSize)
-		// 1. Handle negative values greater than MinInt64 (and)
-		// 2. Handle negative values lesser than MinInt64
-		if intErr == nil && intValue < 0 {
-			return 0, nil
-		} else if intErr != nil && intErr.(*strconv.NumError).Err == strconv.ErrRange && intValue < 0 {
-			return 0, nil
-		}
-
-		return value, err
-	}
-
-	return value, nil
-}
-
-// ParseKeyValue parses a space-separated "name value" kind of cgroup
-// parameter and returns its key as a string, and its value as uint64
-// (ParseUint is used to convert the value). For example,
-// "io_service_bytes 1234" will be returned as "io_service_bytes", 1234.
-func ParseKeyValue(t string) (string, uint64, error) {
-	parts := strings.SplitN(t, " ", 3)
-	if len(parts) != 2 {
-		return "", 0, fmt.Errorf("line %q is not in key value format", t)
-	}
-
-	value, err := ParseUint(parts[1], 10, 64)
-	if err != nil {
-		return "", 0, fmt.Errorf("unable to convert to uint64: %v", err)
-	}
-
-	return parts[0], value, nil
-}
-
-// GetValueByKey reads a key-value pairs from the specified cgroup file,
-// and returns a value of the specified key. ParseUint is used for value
-// conversion.
-func GetValueByKey(path, file, key string) (uint64, error) {
-	content, err := ReadFile(path, file)
-	if err != nil {
-		return 0, err
-	}
-
-	lines := strings.Split(string(content), "\n")
-	for _, line := range lines {
-		arr := strings.Split(line, " ")
-		if len(arr) == 2 && arr[0] == key {
-			return ParseUint(arr[1], 10, 64)
-		}
-	}
-
-	return 0, nil
-}
-
-// GetCgroupParamUint reads a single uint64 value from the specified cgroup file.
-// If the value read is "max", the math.MaxUint64 is returned.
-func GetCgroupParamUint(path, file string) (uint64, error) {
-	contents, err := GetCgroupParamString(path, file)
-	if err != nil {
-		return 0, err
-	}
-	contents = strings.TrimSpace(contents)
-	if contents == "max" {
-		return math.MaxUint64, nil
-	}
-
-	res, err := ParseUint(contents, 10, 64)
-	if err != nil {
-		return res, fmt.Errorf("unable to parse file %q", path+"/"+file)
-	}
-	return res, nil
-}
-
-// GetCgroupParamInt reads a single int64 value from specified cgroup file.
-// If the value read is "max", the math.MaxInt64 is returned.
-func GetCgroupParamInt(path, file string) (int64, error) {
-	contents, err := ReadFile(path, file)
-	if err != nil {
-		return 0, err
-	}
-	contents = strings.TrimSpace(contents)
-	if contents == "max" {
-		return math.MaxInt64, nil
-	}
-
-	res, err := strconv.ParseInt(contents, 10, 64)
-	if err != nil {
-		return res, fmt.Errorf("unable to parse %q as a int from Cgroup file %q", contents, path+"/"+file)
-	}
-	return res, nil
-}
-
-// GetCgroupParamString reads a string from the specified cgroup file.
-func GetCgroupParamString(path, file string) (string, error) {
-	contents, err := ReadFile(path, file)
-	if err != nil {
-		return "", err
-	}
-
-	return strings.TrimSpace(contents), nil
-}

+ 2 - 4
vendor/github.com/opencontainers/runc/libcontainer/cgroups/utils.go

@@ -15,7 +15,6 @@ import (
 	"sync"
 	"sync"
 	"time"
 	"time"
 
 
-	"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
 	"github.com/opencontainers/runc/libcontainer/userns"
 	"github.com/opencontainers/runc/libcontainer/userns"
 	"github.com/sirupsen/logrus"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sys/unix"
 	"golang.org/x/sys/unix"
@@ -88,7 +87,7 @@ func GetAllSubsystems() ([]string, error) {
 		// - freezer: implemented in kernel 5.2
 		// - freezer: implemented in kernel 5.2
 		// We assume these are always available, as it is hard to detect availability.
 		// We assume these are always available, as it is hard to detect availability.
 		pseudo := []string{"devices", "freezer"}
 		pseudo := []string{"devices", "freezer"}
-		data, err := fscommon.ReadFile("/sys/fs/cgroup", "cgroup.controllers")
+		data, err := ReadFile("/sys/fs/cgroup", "cgroup.controllers")
 		if err != nil {
 		if err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
@@ -267,7 +266,6 @@ func RemovePaths(paths map[string]string) (err error) {
 				case retries - 1:
 				case retries - 1:
 					logrus.WithError(err).Error("Failed to remove cgroup")
 					logrus.WithError(err).Error("Failed to remove cgroup")
 				}
 				}
-
 			}
 			}
 			_, err := os.Stat(p)
 			_, err := os.Stat(p)
 			// We need this strange way of checking cgroups existence because
 			// We need this strange way of checking cgroups existence because
@@ -376,7 +374,7 @@ func WriteCgroupProc(dir string, pid int) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	file, err := fscommon.OpenFile(dir, CgroupProcesses, os.O_WRONLY)
+	file, err := OpenFile(dir, CgroupProcesses, os.O_WRONLY)
 	if err != nil {
 	if err != nil {
 		return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
 		return fmt.Errorf("failed to write %v to %v: %v", pid, CgroupProcesses, err)
 	}
 	}

+ 5 - 5
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_linux.go

@@ -13,12 +13,12 @@ const (
 	Thawed    FreezerState = "THAWED"
 	Thawed    FreezerState = "THAWED"
 )
 )
 
 
+// Cgroup holds properties of a cgroup on Linux.
 type Cgroup struct {
 type Cgroup struct {
-	// Deprecated, use Path instead
+	// Name specifies the name of the cgroup
 	Name string `json:"name,omitempty"`
 	Name string `json:"name,omitempty"`
 
 
-	// name of parent of cgroup or slice
-	// Deprecated, use Path instead
+	// Parent specifies the name of parent of cgroup or slice
 	Parent string `json:"parent,omitempty"`
 	Parent string `json:"parent,omitempty"`
 
 
 	// Path specifies the path to cgroups that are created and/or joined by the container.
 	// Path specifies the path to cgroups that are created and/or joined by the container.
@@ -127,8 +127,8 @@ type Resources struct {
 
 
 	// SkipDevices allows to skip configuring device permissions.
 	// SkipDevices allows to skip configuring device permissions.
 	// Used by e.g. kubelet while creating a parent cgroup (kubepods)
 	// Used by e.g. kubelet while creating a parent cgroup (kubepods)
-	// common for many containers.
+	// common for many containers, and by runc update.
 	//
 	//
 	// NOTE it is impossible to start a container which has this flag set.
 	// NOTE it is impossible to start a container which has this flag set.
-	SkipDevices bool `json:"skip_devices"`
+	SkipDevices bool `json:"-"`
 }
 }

+ 2 - 2
vendor/github.com/opencontainers/runc/libcontainer/configs/cgroup_unsupported.go

@@ -2,7 +2,7 @@
 
 
 package configs
 package configs
 
 
+// Cgroup holds properties of a cgroup on Linux
 // TODO Windows: This can ultimately be entirely factored out on Windows as
 // TODO Windows: This can ultimately be entirely factored out on Windows as
 // cgroups are a Unix-specific construct.
 // cgroups are a Unix-specific construct.
-type Cgroup struct {
-}
+type Cgroup struct{}

+ 6 - 4
vendor/github.com/opencontainers/runc/libcontainer/configs/config.go

@@ -208,9 +208,11 @@ type Config struct {
 	RootlessCgroups bool `json:"rootless_cgroups,omitempty"`
 	RootlessCgroups bool `json:"rootless_cgroups,omitempty"`
 }
 }
 
 
-type HookName string
-type HookList []Hook
-type Hooks map[HookName]HookList
+type (
+	HookName string
+	HookList []Hook
+	Hooks    map[HookName]HookList
+)
 
 
 const (
 const (
 	// Prestart commands are executed after the container namespaces are created,
 	// Prestart commands are executed after the container namespaces are created,
@@ -387,7 +389,7 @@ func (c Command) Run(s *specs.State) error {
 	case err := <-errC:
 	case err := <-errC:
 		return err
 		return err
 	case <-timerCh:
 	case <-timerCh:
-		cmd.Process.Kill()
+		_ = cmd.Process.Kill()
 		<-errC
 		<-errC
 		return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
 		return fmt.Errorf("hook ran past specified timeout of %.1fs", c.Timeout.Seconds())
 	}
 	}

+ 0 - 17
vendor/github.com/opencontainers/runc/libcontainer/configs/devices.go

@@ -1,17 +0,0 @@
-package configs
-
-import "github.com/opencontainers/runc/libcontainer/devices"
-
-type (
-	// Deprecated: use libcontainer/devices.Device
-	Device = devices.Device
-
-	// Deprecated: use libcontainer/devices.Rule
-	DeviceRule = devices.Rule
-
-	// Deprecated: use libcontainer/devices.Type
-	DeviceType = devices.Type
-
-	// Deprecated: use libcontainer/devices.Permissions
-	DevicePermissions = devices.Permissions
-)

+ 1 - 1
vendor/github.com/opencontainers/runc/libcontainer/configs/mount.go

@@ -3,7 +3,7 @@ package configs
 const (
 const (
 	// EXT_COPYUP is a directive to copy up the contents of a directory when
 	// EXT_COPYUP is a directive to copy up the contents of a directory when
 	// a tmpfs is mounted over it.
 	// a tmpfs is mounted over it.
-	EXT_COPYUP = 1 << iota
+	EXT_COPYUP = 1 << iota //nolint:golint // ignore "don't use ALL_CAPS" warning
 )
 )
 
 
 type Mount struct {
 type Mount struct {

+ 1 - 2
vendor/github.com/opencontainers/runc/libcontainer/configs/namespaces_unsupported.go

@@ -4,5 +4,4 @@ package configs
 
 
 // Namespace defines configuration for each namespace.  It specifies an
 // Namespace defines configuration for each namespace.  It specifies an
 // alternate path that is able to be joined via setns.
 // alternate path that is able to be joined via setns.
-type Namespace struct {
-}
+type Namespace struct{}

+ 8 - 5
vendor/github.com/opencontainers/runc/libcontainer/configs/network.go

@@ -50,7 +50,10 @@ type Network struct {
 	HairpinMode bool `json:"hairpin_mode"`
 	HairpinMode bool `json:"hairpin_mode"`
 }
 }
 
 
-// Routes can be specified to create entries in the route table as the container is started
+// Route defines a routing table entry.
+//
+// Routes can be specified to create entries in the routing table as the container
+// is started.
 //
 //
 // All of destination, source, and gateway should be either IPv4 or IPv6.
 // All of destination, source, and gateway should be either IPv4 or IPv6.
 // One of the three options must be present, and omitted entries will use their
 // One of the three options must be present, and omitted entries will use their
@@ -58,15 +61,15 @@ type Network struct {
 // gateway to 1.2.3.4 and the interface to eth0 will set up a standard
 // gateway to 1.2.3.4 and the interface to eth0 will set up a standard
 // destination of 0.0.0.0(or *) when viewed in the route table.
 // destination of 0.0.0.0(or *) when viewed in the route table.
 type Route struct {
 type Route struct {
-	// Sets the destination and mask, should be a CIDR.  Accepts IPv4 and IPv6
+	// Destination specifies the destination IP address and mask in the CIDR form.
 	Destination string `json:"destination"`
 	Destination string `json:"destination"`
 
 
-	// Sets the source and mask, should be a CIDR.  Accepts IPv4 and IPv6
+	// Source specifies the source IP address and mask in the CIDR form.
 	Source string `json:"source"`
 	Source string `json:"source"`
 
 
-	// Sets the gateway.  Accepts IPv4 and IPv6
+	// Gateway specifies the gateway IP address.
 	Gateway string `json:"gateway"`
 	Gateway string `json:"gateway"`
 
 
-	// The device to set this route up for, for example: eth0
+	// InterfaceName specifies the device to set this route up for, for example eth0.
 	InterfaceName string `json:"interface_name"`
 	InterfaceName string `json:"interface_name"`
 }
 }

+ 5 - 6
vendor/github.com/opencontainers/runc/libcontainer/devices/device_unix.go

@@ -11,10 +11,8 @@ import (
 	"golang.org/x/sys/unix"
 	"golang.org/x/sys/unix"
 )
 )
 
 
-var (
-	// ErrNotADevice denotes that a file is not a valid linux device.
-	ErrNotADevice = errors.New("not a device node")
-)
+// ErrNotADevice denotes that a file is not a valid linux device.
+var ErrNotADevice = errors.New("not a device node")
 
 
 // Testing dependencies
 // Testing dependencies
 var (
 var (
@@ -29,8 +27,9 @@ func mkDev(d *Rule) (uint64, error) {
 	return unix.Mkdev(uint32(d.Major), uint32(d.Minor)), nil
 	return unix.Mkdev(uint32(d.Major), uint32(d.Minor)), nil
 }
 }
 
 
-// Given the path to a device and its cgroup_permissions(which cannot be easily queried) look up the
-// information about a linux device and return that information as a Device struct.
+// DeviceFromPath takes the path to a device and its cgroup_permissions (which
+// cannot be easily queried) to look up the information about a linux device
+// and returns that information as a Device struct.
 func DeviceFromPath(path, permissions string) (*Device, error) {
 func DeviceFromPath(path, permissions string) (*Device, error) {
 	var stat unix.Stat_t
 	var stat unix.Stat_t
 	err := unixLstat(path, &stat)
 	err := unixLstat(path, &stat)

+ 3 - 3
vendor/github.com/opencontainers/runc/libcontainer/nsenter/test/escape.go

@@ -14,7 +14,7 @@ import (
 	"unsafe"
 	"unsafe"
 )
 )
 
 
-func testEscapeJsonString(t *testing.T, input, want string) {
+func testEscapeJSONString(t *testing.T, input, want string) {
 	in := C.CString(input)
 	in := C.CString(input)
 	out := C.escape_json_string(in)
 	out := C.escape_json_string(in)
 	got := C.GoString(out)
 	got := C.GoString(out)
@@ -25,7 +25,7 @@ func testEscapeJsonString(t *testing.T, input, want string) {
 	}
 	}
 }
 }
 
 
-func testEscapeJson(t *testing.T) {
+func testEscapeJSON(t *testing.T) {
 	testCases := []struct {
 	testCases := []struct {
 		input, output string
 		input, output string
 	}{
 	}{
@@ -48,6 +48,6 @@ func testEscapeJson(t *testing.T) {
 	}
 	}
 
 
 	for _, tc := range testCases {
 	for _, tc := range testCases {
-		testEscapeJsonString(t, tc.input, tc.output)
+		testEscapeJSONString(t, tc.input, tc.output)
 	}
 	}
 }
 }

+ 74 - 42
vendor/github.com/opencontainers/runc/libcontainer/user/user.go

@@ -2,6 +2,7 @@ package user
 
 
 import (
 import (
 	"bufio"
 	"bufio"
+	"bytes"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
@@ -11,19 +12,17 @@ import (
 )
 )
 
 
 const (
 const (
-	minId = 0
-	maxId = 1<<31 - 1 //for 32-bit systems compatibility
+	minID = 0
+	maxID = 1<<31 - 1 // for 32-bit systems compatibility
 )
 )
 
 
 var (
 var (
-	// The current operating system does not provide the required data for user lookups.
-	ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data")
-
-	// No matching entries found in file.
+	// ErrNoPasswdEntries is returned if no matching entries were found in /etc/group.
 	ErrNoPasswdEntries = errors.New("no matching entries in passwd file")
 	ErrNoPasswdEntries = errors.New("no matching entries in passwd file")
-	ErrNoGroupEntries  = errors.New("no matching entries in group file")
-
-	ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minId, maxId)
+	// ErrNoGroupEntries is returned if no matching entries were found in /etc/passwd.
+	ErrNoGroupEntries = errors.New("no matching entries in group file")
+	// ErrRange is returned if a UID or GID is outside of the valid range.
+	ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minID, maxID)
 )
 )
 
 
 type User struct {
 type User struct {
@@ -57,11 +56,11 @@ type IDMap struct {
 	Count    int64
 	Count    int64
 }
 }
 
 
-func parseLine(line string, v ...interface{}) {
-	parseParts(strings.Split(line, ":"), v...)
+func parseLine(line []byte, v ...interface{}) {
+	parseParts(bytes.Split(line, []byte(":")), v...)
 }
 }
 
 
-func parseParts(parts []string, v ...interface{}) {
+func parseParts(parts [][]byte, v ...interface{}) {
 	if len(parts) == 0 {
 	if len(parts) == 0 {
 		return
 		return
 	}
 	}
@@ -77,16 +76,16 @@ func parseParts(parts []string, v ...interface{}) {
 		// This is legit.
 		// This is legit.
 		switch e := v[i].(type) {
 		switch e := v[i].(type) {
 		case *string:
 		case *string:
-			*e = p
+			*e = string(p)
 		case *int:
 		case *int:
 			// "numbers", with conversion errors ignored because of some misbehaving configuration files.
 			// "numbers", with conversion errors ignored because of some misbehaving configuration files.
-			*e, _ = strconv.Atoi(p)
+			*e, _ = strconv.Atoi(string(p))
 		case *int64:
 		case *int64:
-			*e, _ = strconv.ParseInt(p, 10, 64)
+			*e, _ = strconv.ParseInt(string(p), 10, 64)
 		case *[]string:
 		case *[]string:
 			// Comma-separated lists.
 			// Comma-separated lists.
-			if p != "" {
-				*e = strings.Split(p, ",")
+			if len(p) != 0 {
+				*e = strings.Split(string(p), ",")
 			} else {
 			} else {
 				*e = []string{}
 				*e = []string{}
 			}
 			}
@@ -130,8 +129,8 @@ func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) {
 	)
 	)
 
 
 	for s.Scan() {
 	for s.Scan() {
-		line := strings.TrimSpace(s.Text())
-		if line == "" {
+		line := bytes.TrimSpace(s.Bytes())
+		if len(line) == 0 {
 			continue
 			continue
 		}
 		}
 
 
@@ -181,15 +180,53 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {
 	if r == nil {
 	if r == nil {
 		return nil, fmt.Errorf("nil source for group-formatted data")
 		return nil, fmt.Errorf("nil source for group-formatted data")
 	}
 	}
+	rd := bufio.NewReader(r)
+	out := []Group{}
 
 
-	var (
-		s   = bufio.NewScanner(r)
-		out = []Group{}
-	)
+	// Read the file line-by-line.
+	for {
+		var (
+			isPrefix  bool
+			wholeLine []byte
+			err       error
+		)
 
 
-	for s.Scan() {
-		text := s.Text()
-		if text == "" {
+		// Read the next line. We do so in chunks (as much as reader's
+		// buffer is able to keep), check if we read enough columns
+		// already on each step and store final result in wholeLine.
+		for {
+			var line []byte
+			line, isPrefix, err = rd.ReadLine()
+
+			if err != nil {
+				// We should return no error if EOF is reached
+				// without a match.
+				if err == io.EOF { //nolint:errorlint // comparison with io.EOF is legit, https://github.com/polyfloyd/go-errorlint/pull/12
+					err = nil
+				}
+				return out, err
+			}
+
+			// Simple common case: line is short enough to fit in a
+			// single reader's buffer.
+			if !isPrefix && len(wholeLine) == 0 {
+				wholeLine = line
+				break
+			}
+
+			wholeLine = append(wholeLine, line...)
+
+			// Check if we read the whole line already.
+			if !isPrefix {
+				break
+			}
+		}
+
+		// There's no spec for /etc/passwd or /etc/group, but we try to follow
+		// the same rules as the glibc parser, which allows comments and blank
+		// space at the beginning of a line.
+		wholeLine = bytes.TrimSpace(wholeLine)
+		if len(wholeLine) == 0 || wholeLine[0] == '#' {
 			continue
 			continue
 		}
 		}
 
 
@@ -199,17 +236,12 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) {
 		//  root:x:0:root
 		//  root:x:0:root
 		//  adm:x:4:root,adm,daemon
 		//  adm:x:4:root,adm,daemon
 		p := Group{}
 		p := Group{}
-		parseLine(text, &p.Name, &p.Pass, &p.Gid, &p.List)
+		parseLine(wholeLine, &p.Name, &p.Pass, &p.Gid, &p.List)
 
 
 		if filter == nil || filter(p) {
 		if filter == nil || filter(p) {
 			out = append(out, p)
 			out = append(out, p)
 		}
 		}
 	}
 	}
-	if err := s.Err(); err != nil {
-		return nil, err
-	}
-
-	return out, nil
 }
 }
 
 
 type ExecUser struct {
 type ExecUser struct {
@@ -280,7 +312,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
 
 
 	// Allow for userArg to have either "user" syntax, or optionally "user:group" syntax
 	// Allow for userArg to have either "user" syntax, or optionally "user:group" syntax
 	var userArg, groupArg string
 	var userArg, groupArg string
-	parseLine(userSpec, &userArg, &groupArg)
+	parseLine([]byte(userSpec), &userArg, &groupArg)
 
 
 	// Convert userArg and groupArg to be numeric, so we don't have to execute
 	// Convert userArg and groupArg to be numeric, so we don't have to execute
 	// Atoi *twice* for each iteration over lines.
 	// Atoi *twice* for each iteration over lines.
@@ -328,7 +360,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
 		user.Uid = uidArg
 		user.Uid = uidArg
 
 
 		// Must be inside valid uid range.
 		// Must be inside valid uid range.
-		if user.Uid < minId || user.Uid > maxId {
+		if user.Uid < minID || user.Uid > maxID {
 			return nil, ErrRange
 			return nil, ErrRange
 		}
 		}
 
 
@@ -377,7 +409,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
 				user.Gid = gidArg
 				user.Gid = gidArg
 
 
 				// Must be inside valid gid range.
 				// Must be inside valid gid range.
-				if user.Gid < minId || user.Gid > maxId {
+				if user.Gid < minID || user.Gid > maxID {
 					return nil, ErrRange
 					return nil, ErrRange
 				}
 				}
 
 
@@ -401,7 +433,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
 // or the given group data is nil, the id will be returned as-is
 // or the given group data is nil, the id will be returned as-is
 // provided it is in the legal range.
 // provided it is in the legal range.
 func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) {
 func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) {
-	var groups = []Group{}
+	groups := []Group{}
 	if group != nil {
 	if group != nil {
 		var err error
 		var err error
 		groups, err = ParseGroupFilter(group, func(g Group) bool {
 		groups, err = ParseGroupFilter(group, func(g Group) bool {
@@ -439,7 +471,7 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err
 				return nil, fmt.Errorf("Unable to find group %s", ag)
 				return nil, fmt.Errorf("Unable to find group %s", ag)
 			}
 			}
 			// Ensure gid is inside gid range.
 			// Ensure gid is inside gid range.
-			if gid < minId || gid > maxId {
+			if gid < minID || gid > maxID {
 				return nil, ErrRange
 				return nil, ErrRange
 			}
 			}
 			gidMap[int(gid)] = struct{}{}
 			gidMap[int(gid)] = struct{}{}
@@ -498,8 +530,8 @@ func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) {
 	)
 	)
 
 
 	for s.Scan() {
 	for s.Scan() {
-		line := strings.TrimSpace(s.Text())
-		if line == "" {
+		line := bytes.TrimSpace(s.Bytes())
+		if len(line) == 0 {
 			continue
 			continue
 		}
 		}
 
 
@@ -551,14 +583,14 @@ func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) {
 	)
 	)
 
 
 	for s.Scan() {
 	for s.Scan() {
-		line := strings.TrimSpace(s.Text())
-		if line == "" {
+		line := bytes.TrimSpace(s.Bytes())
+		if len(line) == 0 {
 			continue
 			continue
 		}
 		}
 
 
 		// see: man 7 user_namespaces
 		// see: man 7 user_namespaces
 		p := IDMap{}
 		p := IDMap{}
-		parseParts(strings.Fields(line), &p.ID, &p.ParentID, &p.Count)
+		parseParts(bytes.Fields(line), &p.ID, &p.ParentID, &p.Count)
 
 
 		if filter == nil || filter(p) {
 		if filter == nil || filter(p) {
 			out = append(out, p)
 			out = append(out, p)