Browse code

vendor runc library to v1.0.0-rc92

Signed-off-by: Jintao Zhang <zhangjintao9020@gmail.com>

Jintao Zhang authored on 2020/08/12 18:11:55
Showing 11 changed files
... ...
@@ -83,10 +83,11 @@ google.golang.org/grpc                              f495f5b15ae7ccda3b38c53a1bfc
83 83
 # the containerd project first, and update both after that is merged.
84 84
 # This commit does not need to match RUNC_COMMIT as it is used for helper
85 85
 # packages but should be newer or equal.
86
-github.com/opencontainers/runc                      67169a9d43456ff0d5ae12b967acb8e366e2f181 # v1.0.0-rc91-48-g67169a9d
87
-github.com/opencontainers/runtime-spec              237cc4f519e2e8f9b235bacccfa8ef5a84df2875 # v1.0.3-0.20200520003142-237cc4f519e2
86
+github.com/opencontainers/runc                      ff819c7e9184c13b7c2607fe6c30ae19403a7aff # v1.0.0-rc92
87
+github.com/opencontainers/runtime-spec              4d89ac9fbff6c455f46a5bb59c6b1bb7184a5e43 # v1.0.3-0.20200728170252-4d89ac9fbff6
88 88
 github.com/opencontainers/image-spec                d60099175f88c47cd379c4738d158884749ed235 # v1.0.1
89 89
 github.com/seccomp/libseccomp-golang                689e3c1541a84461afc49c1c87352a6cedf72e9c # v0.9.1
90
+github.com/cyphar/filepath-securejoin               a261ee33d7a517f054effbf451841abaafe3e0fd # v0.2.2
90 91
 
91 92
 # go-systemd v17 is required by github.com/coreos/pkg/capnslog/journald_formatter.go
92 93
 github.com/coreos/go-systemd                        39ca1b05acc7ad1220e09f133283b8859a8b71ab # v17
93 94
new file mode 100644
... ...
@@ -0,0 +1,28 @@
0
+Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
1
+Copyright (C) 2017 SUSE LLC. All rights reserved.
2
+
3
+Redistribution and use in source and binary forms, with or without
4
+modification, are permitted provided that the following conditions are
5
+met:
6
+
7
+   * Redistributions of source code must retain the above copyright
8
+notice, this list of conditions and the following disclaimer.
9
+   * Redistributions in binary form must reproduce the above
10
+copyright notice, this list of conditions and the following disclaimer
11
+in the documentation and/or other materials provided with the
12
+distribution.
13
+   * Neither the name of Google Inc. nor the names of its
14
+contributors may be used to endorse or promote products derived from
15
+this software without specific prior written permission.
16
+
17
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0 28
new file mode 100644
... ...
@@ -0,0 +1,65 @@
0
+## `filepath-securejoin` ##
1
+
2
+[![Build Status](https://travis-ci.org/cyphar/filepath-securejoin.svg?branch=master)](https://travis-ci.org/cyphar/filepath-securejoin)
3
+
4
+An implementation of `SecureJoin`, a [candidate for inclusion in the Go
5
+standard library][go#20126]. The purpose of this function is to be a "secure"
6
+alternative to `filepath.Join`, and in particular it provides certain
7
+guarantees that are not provided by `filepath.Join`.
8
+
9
+This is the function prototype:
10
+
11
+```go
12
+func SecureJoin(root, unsafePath string) (string, error)
13
+```
14
+
15
+This library **guarantees** the following:
16
+
17
+* If no error is set, the resulting string **must** be a child path of
18
+  `SecureJoin` and will not contain any symlink path components (they will all
19
+  be expanded).
20
+
21
+* When expanding symlinks, all symlink path components **must** be resolved
22
+  relative to the provided root. In particular, this can be considered a
23
+  userspace implementation of how `chroot(2)` operates on file paths. Note that
24
+  these symlinks will **not** be expanded lexically (`filepath.Clean` is not
25
+  called on the input before processing).
26
+
27
+* Non-existant path components are unaffected by `SecureJoin` (similar to
28
+  `filepath.EvalSymlinks`'s semantics).
29
+
30
+* The returned path will always be `filepath.Clean`ed and thus not contain any
31
+  `..` components.
32
+
33
+A (trivial) implementation of this function on GNU/Linux systems could be done
34
+with the following (note that this requires root privileges and is far more
35
+opaque than the implementation in this library, and also requires that
36
+`readlink` is inside the `root` path):
37
+
38
+```go
39
+package securejoin
40
+
41
+import (
42
+	"os/exec"
43
+	"path/filepath"
44
+)
45
+
46
+func SecureJoin(root, unsafePath string) (string, error) {
47
+	unsafePath = string(filepath.Separator) + unsafePath
48
+	cmd := exec.Command("chroot", root,
49
+		"readlink", "--canonicalize-missing", "--no-newline", unsafePath)
50
+	output, err := cmd.CombinedOutput()
51
+	if err != nil {
52
+		return "", err
53
+	}
54
+	expanded := string(output)
55
+	return filepath.Join(root, expanded), nil
56
+}
57
+```
58
+
59
+[go#20126]: https://github.com/golang/go/issues/20126
60
+
61
+### License ###
62
+
63
+The license of this project is the same as Go, which is a BSD 3-clause license
64
+available in the `LICENSE` file.
0 65
new file mode 100644
... ...
@@ -0,0 +1,134 @@
0
+// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved.
1
+// Copyright (C) 2017 SUSE LLC. All rights reserved.
2
+// Use of this source code is governed by a BSD-style
3
+// license that can be found in the LICENSE file.
4
+
5
+// Package securejoin is an implementation of the hopefully-soon-to-be-included
6
+// SecureJoin helper that is meant to be part of the "path/filepath" package.
7
+// The purpose of this project is to provide a PoC implementation to make the
8
+// SecureJoin proposal (https://github.com/golang/go/issues/20126) more
9
+// tangible.
10
+package securejoin
11
+
12
+import (
13
+	"bytes"
14
+	"os"
15
+	"path/filepath"
16
+	"strings"
17
+	"syscall"
18
+
19
+	"github.com/pkg/errors"
20
+)
21
+
22
+// ErrSymlinkLoop is returned by SecureJoinVFS when too many symlinks have been
23
+// evaluated in attempting to securely join the two given paths.
24
+var ErrSymlinkLoop = errors.Wrap(syscall.ELOOP, "secure join")
25
+
26
+// IsNotExist tells you if err is an error that implies that either the path
27
+// accessed does not exist (or path components don't exist). This is
28
+// effectively a more broad version of os.IsNotExist.
29
+func IsNotExist(err error) bool {
30
+	// If it's a bone-fide ENOENT just bail.
31
+	if os.IsNotExist(errors.Cause(err)) {
32
+		return true
33
+	}
34
+
35
+	// Check that it's not actually an ENOTDIR, which in some cases is a more
36
+	// convoluted case of ENOENT (usually involving weird paths).
37
+	var errno error
38
+	switch err := errors.Cause(err).(type) {
39
+	case *os.PathError:
40
+		errno = err.Err
41
+	case *os.LinkError:
42
+		errno = err.Err
43
+	case *os.SyscallError:
44
+		errno = err.Err
45
+	}
46
+	return errno == syscall.ENOTDIR || errno == syscall.ENOENT
47
+}
48
+
49
+// SecureJoinVFS joins the two given path components (similar to Join) except
50
+// that the returned path is guaranteed to be scoped inside the provided root
51
+// path (when evaluated). Any symbolic links in the path are evaluated with the
52
+// given root treated as the root of the filesystem, similar to a chroot. The
53
+// filesystem state is evaluated through the given VFS interface (if nil, the
54
+// standard os.* family of functions are used).
55
+//
56
+// Note that the guarantees provided by this function only apply if the path
57
+// components in the returned string are not modified (in other words are not
58
+// replaced with symlinks on the filesystem) after this function has returned.
59
+// Such a symlink race is necessarily out-of-scope of SecureJoin.
60
+func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) {
61
+	// Use the os.* VFS implementation if none was specified.
62
+	if vfs == nil {
63
+		vfs = osVFS{}
64
+	}
65
+
66
+	var path bytes.Buffer
67
+	n := 0
68
+	for unsafePath != "" {
69
+		if n > 255 {
70
+			return "", ErrSymlinkLoop
71
+		}
72
+
73
+		// Next path component, p.
74
+		i := strings.IndexRune(unsafePath, filepath.Separator)
75
+		var p string
76
+		if i == -1 {
77
+			p, unsafePath = unsafePath, ""
78
+		} else {
79
+			p, unsafePath = unsafePath[:i], unsafePath[i+1:]
80
+		}
81
+
82
+		// Create a cleaned path, using the lexical semantics of /../a, to
83
+		// create a "scoped" path component which can safely be joined to fullP
84
+		// for evaluation. At this point, path.String() doesn't contain any
85
+		// symlink components.
86
+		cleanP := filepath.Clean(string(filepath.Separator) + path.String() + p)
87
+		if cleanP == string(filepath.Separator) {
88
+			path.Reset()
89
+			continue
90
+		}
91
+		fullP := filepath.Clean(root + cleanP)
92
+
93
+		// Figure out whether the path is a symlink.
94
+		fi, err := vfs.Lstat(fullP)
95
+		if err != nil && !IsNotExist(err) {
96
+			return "", err
97
+		}
98
+		// Treat non-existent path components the same as non-symlinks (we
99
+		// can't do any better here).
100
+		if IsNotExist(err) || fi.Mode()&os.ModeSymlink == 0 {
101
+			path.WriteString(p)
102
+			path.WriteRune(filepath.Separator)
103
+			continue
104
+		}
105
+
106
+		// Only increment when we actually dereference a link.
107
+		n++
108
+
109
+		// It's a symlink, expand it by prepending it to the yet-unparsed path.
110
+		dest, err := vfs.Readlink(fullP)
111
+		if err != nil {
112
+			return "", err
113
+		}
114
+		// Absolute symlinks reset any work we've already done.
115
+		if filepath.IsAbs(dest) {
116
+			path.Reset()
117
+		}
118
+		unsafePath = dest + string(filepath.Separator) + unsafePath
119
+	}
120
+
121
+	// We have to clean path.String() here because it may contain '..'
122
+	// components that are entirely lexical, but would be misleading otherwise.
123
+	// And finally do a final clean to ensure that root is also lexically
124
+	// clean.
125
+	fullP := filepath.Clean(string(filepath.Separator) + path.String())
126
+	return filepath.Clean(root + fullP), nil
127
+}
128
+
129
+// SecureJoin is a wrapper around SecureJoinVFS that just uses the os.* library
130
+// of functions as the VFS. If in doubt, use this function over SecureJoinVFS.
131
+func SecureJoin(root, unsafePath string) (string, error) {
132
+	return SecureJoinVFS(root, unsafePath, nil)
133
+}
0 134
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+github.com/pkg/errors v0.8.0
0 1
new file mode 100644
... ...
@@ -0,0 +1,41 @@
0
+// Copyright (C) 2017 SUSE LLC. All rights reserved.
1
+// Use of this source code is governed by a BSD-style
2
+// license that can be found in the LICENSE file.
3
+
4
+package securejoin
5
+
6
+import "os"
7
+
8
+// In future this should be moved into a separate package, because now there
9
+// are several projects (umoci and go-mtree) that are using this sort of
10
+// interface.
11
+
12
+// VFS is the minimal interface necessary to use SecureJoinVFS. A nil VFS is
13
+// equivalent to using the standard os.* family of functions. This is mainly
14
+// used for the purposes of mock testing, but also can be used to otherwise use
15
+// SecureJoin with VFS-like system.
16
+type VFS interface {
17
+	// Lstat returns a FileInfo describing the named file. If the file is a
18
+	// symbolic link, the returned FileInfo describes the symbolic link. Lstat
19
+	// makes no attempt to follow the link. These semantics are identical to
20
+	// os.Lstat.
21
+	Lstat(name string) (os.FileInfo, error)
22
+
23
+	// Readlink returns the destination of the named symbolic link. These
24
+	// semantics are identical to os.Readlink.
25
+	Readlink(name string) (string, error)
26
+}
27
+
28
+// osVFS is the "nil" VFS, in that it just passes everything through to the os
29
+// module.
30
+type osVFS struct{}
31
+
32
+// Lstat returns a FileInfo describing the named file. If the file is a
33
+// symbolic link, the returned FileInfo describes the symbolic link. Lstat
34
+// makes no attempt to follow the link. These semantics are identical to
35
+// os.Lstat.
36
+func (o osVFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) }
37
+
38
+// Readlink returns the destination of the named symbolic link. These
39
+// semantics are identical to os.Readlink.
40
+func (o osVFS) Readlink(name string) (string, error) { return os.Readlink(name) }
... ...
@@ -3,18 +3,18 @@ module github.com/opencontainers/runc
3 3
 go 1.14
4 4
 
5 5
 require (
6
-	github.com/checkpoint-restore/go-criu/v4 v4.0.2
6
+	github.com/checkpoint-restore/go-criu/v4 v4.1.0
7 7
 	github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775
8 8
 	github.com/containerd/console v1.0.0
9
-	github.com/coreos/go-systemd/v22 v22.0.0
9
+	github.com/coreos/go-systemd/v22 v22.1.0
10 10
 	github.com/cyphar/filepath-securejoin v0.2.2
11 11
 	github.com/docker/go-units v0.4.0
12 12
 	github.com/godbus/dbus/v5 v5.0.3
13
-	github.com/golang/protobuf v1.3.5
13
+	github.com/golang/protobuf v1.4.2
14 14
 	github.com/moby/sys/mountinfo v0.1.3
15
-	github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
16
-	github.com/opencontainers/runtime-spec v1.0.3-0.20200520003142-237cc4f519e2
17
-	github.com/opencontainers/selinux v1.5.1
15
+	github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976
16
+	github.com/opencontainers/runtime-spec v1.0.3-0.20200728170252-4d89ac9fbff6
17
+	github.com/opencontainers/selinux v1.6.0
18 18
 	github.com/pkg/errors v0.9.1
19 19
 	github.com/seccomp/libseccomp-golang v0.9.1
20 20
 	github.com/sirupsen/logrus v1.6.0
... ...
@@ -22,5 +22,5 @@ require (
22 22
 	// NOTE: urfave/cli must be <= v1.22.1 due to a regression: https://github.com/urfave/cli/issues/1092
23 23
 	github.com/urfave/cli v1.22.1
24 24
 	github.com/vishvananda/netlink v1.1.0
25
-	golang.org/x/sys v0.0.0-20200327173247-9dae0f8f5775
25
+	golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1
26 26
 )
... ...
@@ -8,6 +8,10 @@ import (
8 8
 	"os"
9 9
 	"path/filepath"
10 10
 	"strings"
11
+	"syscall"
12
+
13
+	securejoin "github.com/cyphar/filepath-securejoin"
14
+	"golang.org/x/sys/unix"
11 15
 )
12 16
 
13 17
 // Code in this source file are specific to cgroup v1,
... ...
@@ -15,6 +19,7 @@ import (
15 15
 
16 16
 const (
17 17
 	CgroupNamePrefix = "name="
18
+	defaultPrefix    = "/sys/fs/cgroup"
18 19
 )
19 20
 
20 21
 var (
... ...
@@ -43,11 +48,59 @@ func IsNotFound(err error) bool {
43 43
 	return ok
44 44
 }
45 45
 
46
+func tryDefaultPath(cgroupPath, subsystem string) string {
47
+	if !strings.HasPrefix(defaultPrefix, cgroupPath) {
48
+		return ""
49
+	}
50
+
51
+	// remove possible prefix
52
+	subsystem = strings.TrimPrefix(subsystem, CgroupNamePrefix)
53
+
54
+	// Make sure we're still under defaultPrefix, and resolve
55
+	// a possible symlink (like cpu -> cpu,cpuacct).
56
+	path, err := securejoin.SecureJoin(defaultPrefix, subsystem)
57
+	if err != nil {
58
+		return ""
59
+	}
60
+
61
+	// (1) path should be a directory.
62
+	st, err := os.Lstat(path)
63
+	if err != nil || !st.IsDir() {
64
+		return ""
65
+	}
66
+
67
+	// (2) path should be a mount point.
68
+	pst, err := os.Lstat(filepath.Dir(path))
69
+	if err != nil {
70
+		return ""
71
+	}
72
+
73
+	if st.Sys().(*syscall.Stat_t).Dev == pst.Sys().(*syscall.Stat_t).Dev {
74
+		// parent dir has the same dev -- path is not a mount point
75
+		return ""
76
+	}
77
+
78
+	// (3) path should have 'cgroup' fs type.
79
+	fst := unix.Statfs_t{}
80
+	err = unix.Statfs(path, &fst)
81
+	if err != nil || fst.Type != unix.CGROUP_SUPER_MAGIC {
82
+		return ""
83
+	}
84
+
85
+	return path
86
+}
87
+
46 88
 // https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt
47 89
 func FindCgroupMountpoint(cgroupPath, subsystem string) (string, error) {
48 90
 	if IsCgroup2UnifiedMode() {
49 91
 		return "", errUnified
50 92
 	}
93
+
94
+	// Avoid parsing mountinfo by trying the default path first, if possible.
95
+	if path := tryDefaultPath(cgroupPath, subsystem); path != "" {
96
+		return path, nil
97
+	}
98
+
51 99
 	mnt, _, err := FindCgroupMountpointAndRoot(cgroupPath, subsystem)
52 100
 	return mnt, err
53 101
 }
... ...
@@ -57,9 +110,7 @@ func FindCgroupMountpointAndRoot(cgroupPath, subsystem string) (string, string,
57 57
 		return "", "", errUnified
58 58
 	}
59 59
 
60
-	// We are not using mount.GetMounts() because it's super-inefficient,
61
-	// parsing it directly sped up x10 times because of not using Sscanf.
62
-	// It was one of two major performance drawbacks in container start.
60
+	// Avoid parsing mountinfo by checking if subsystem is valid/available.
63 61
 	if !isSubsystemAvailable(subsystem) {
64 62
 		return "", "", NewNotFoundError(subsystem)
65 63
 	}
... ...
@@ -239,15 +239,6 @@ const (
239 239
 	Poststop = "poststop"
240 240
 )
241 241
 
242
-// TODO move this to runtime-spec
243
-// See: https://github.com/opencontainers/runtime-spec/pull/1046
244
-const (
245
-	Creating = "creating"
246
-	Created  = "created"
247
-	Running  = "running"
248
-	Stopped  = "stopped"
249
-)
250
-
251 242
 type Capabilities struct {
252 243
 	// Bounding is the set of capabilities checked by the kernel.
253 244
 	Bounding []string
... ...
@@ -90,7 +90,7 @@ type User struct {
90 90
 	// GID is the group id.
91 91
 	GID uint32 `json:"gid" platform:"linux,solaris"`
92 92
 	// Umask is the umask for the init process.
93
-	Umask uint32 `json:"umask,omitempty" platform:"linux,solaris"`
93
+	Umask *uint32 `json:"umask,omitempty" platform:"linux,solaris"`
94 94
 	// AdditionalGids are additional group ids set for the container's process.
95 95
 	AdditionalGids []uint32 `json:"additionalGids,omitempty" platform:"linux,solaris"`
96 96
 	// Username is the user name.
... ...
@@ -635,12 +635,13 @@ type LinuxSeccompAction string
635 635
 
636 636
 // Define actions for Seccomp rules
637 637
 const (
638
-	ActKill  LinuxSeccompAction = "SCMP_ACT_KILL"
639
-	ActTrap  LinuxSeccompAction = "SCMP_ACT_TRAP"
640
-	ActErrno LinuxSeccompAction = "SCMP_ACT_ERRNO"
641
-	ActTrace LinuxSeccompAction = "SCMP_ACT_TRACE"
642
-	ActAllow LinuxSeccompAction = "SCMP_ACT_ALLOW"
643
-	ActLog   LinuxSeccompAction = "SCMP_ACT_LOG"
638
+	ActKill        LinuxSeccompAction = "SCMP_ACT_KILL"
639
+	ActKillProcess LinuxSeccompAction = "SCMP_ACT_KILL_PROCESS"
640
+	ActTrap        LinuxSeccompAction = "SCMP_ACT_TRAP"
641
+	ActErrno       LinuxSeccompAction = "SCMP_ACT_ERRNO"
642
+	ActTrace       LinuxSeccompAction = "SCMP_ACT_TRACE"
643
+	ActAllow       LinuxSeccompAction = "SCMP_ACT_ALLOW"
644
+	ActLog         LinuxSeccompAction = "SCMP_ACT_LOG"
644 645
 )
645 646
 
646 647
 // LinuxSeccompOperator used to match syscall arguments in Seccomp
... ...
@@ -1,5 +1,23 @@
1 1
 package specs
2 2
 
3
+// ContainerState represents the state of a container.
4
+type ContainerState string
5
+
6
+const (
7
+	// StateCreating indicates that the container is being created
8
+	StateCreating ContainerState  = "creating"
9
+
10
+	// StateCreated indicates that the runtime has finished the create operation
11
+	StateCreated ContainerState  = "created"
12
+
13
+	// StateRunning indicates that the container process has executed the
14
+	// user-specified program but has not exited
15
+	StateRunning ContainerState  = "running"
16
+
17
+	// StateStopped indicates that the container process has exited
18
+	StateStopped ContainerState  = "stopped"
19
+)
20
+
3 21
 // State holds information about the runtime state of the container.
4 22
 type State struct {
5 23
 	// Version is the version of the specification that is supported.
... ...
@@ -7,7 +25,7 @@ type State struct {
7 7
 	// ID is the container ID
8 8
 	ID string `json:"id"`
9 9
 	// Status is the runtime status of the container.
10
-	Status string `json:"status"`
10
+	Status ContainerState `json:"status"`
11 11
 	// Pid is the process ID for the container process.
12 12
 	Pid int `json:"pid,omitempty"`
13 13
 	// Bundle is the path to the container's bundle directory.