Browse code

daemon: use containerd/sys to detect UserNamespaces

The implementation in libcontainer/system is quite complicated,
and we only use it to detect if user-namespaces are enabled.

In addition, the implementation in containerd uses a sync.Once,
so that detection (and reading/parsing `/proc/self/uid_map`) is
only performed once.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2020/06/15 20:06:08
Showing 8 changed files
... ...
@@ -27,6 +27,7 @@ import (
27 27
 	"github.com/containerd/containerd/defaults"
28 28
 	"github.com/containerd/containerd/pkg/dialer"
29 29
 	"github.com/containerd/containerd/remotes/docker"
30
+	"github.com/containerd/containerd/sys"
30 31
 	"github.com/docker/docker/api/types"
31 32
 	containertypes "github.com/docker/docker/api/types/container"
32 33
 	"github.com/docker/docker/api/types/swarm"
... ...
@@ -42,7 +43,6 @@ import (
42 42
 	"github.com/docker/docker/errdefs"
43 43
 	bkconfig "github.com/moby/buildkit/cmd/buildkitd/config"
44 44
 	"github.com/moby/buildkit/util/resolver"
45
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
46 45
 	"github.com/sirupsen/logrus"
47 46
 
48 47
 	// register graph drivers
... ...
@@ -1040,7 +1040,7 @@ func NewDaemon(ctx context.Context, config *config.Config, pluginStore *plugin.S
1040 1040
 	sysInfo := d.RawSysInfo(false)
1041 1041
 	// Check if Devices cgroup is mounted, it is hard requirement for container security,
1042 1042
 	// on Linux.
1043
-	if runtime.GOOS == "linux" && !sysInfo.CgroupDevicesEnabled && !rsystem.RunningInUserNS() {
1043
+	if runtime.GOOS == "linux" && !sysInfo.CgroupDevicesEnabled && !sys.RunningInUserNS() {
1044 1044
 		return nil, errors.New("Devices cgroup isn't mounted")
1045 1045
 	}
1046 1046
 
... ...
@@ -18,6 +18,7 @@ import (
18 18
 
19 19
 	statsV1 "github.com/containerd/cgroups/stats/v1"
20 20
 	statsV2 "github.com/containerd/cgroups/v2/stats"
21
+	"github.com/containerd/containerd/sys"
21 22
 	"github.com/docker/docker/api/types"
22 23
 	"github.com/docker/docker/api/types/blkiodev"
23 24
 	pblkiodev "github.com/docker/docker/api/types/blkiodev"
... ...
@@ -44,7 +45,6 @@ import (
44 44
 	lntypes "github.com/docker/libnetwork/types"
45 45
 	"github.com/moby/sys/mount"
46 46
 	"github.com/opencontainers/runc/libcontainer/cgroups"
47
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
48 47
 	specs "github.com/opencontainers/runtime-spec/specs-go"
49 48
 	"github.com/opencontainers/selinux/go-selinux/label"
50 49
 	"github.com/pkg/errors"
... ...
@@ -1668,7 +1668,7 @@ func setMayDetachMounts() error {
1668 1668
 		// Setting may_detach_mounts does not work in an
1669 1669
 		// unprivileged container. Ignore the error, but log
1670 1670
 		// it if we appear not to be in that situation.
1671
-		if !rsystem.RunningInUserNS() {
1671
+		if !sys.RunningInUserNS() {
1672 1672
 			logrus.Debugf("Permission denied writing %q to /proc/sys/fs/may_detach_mounts", "1")
1673 1673
 		}
1674 1674
 		return nil
... ...
@@ -1688,7 +1688,7 @@ func setupOOMScoreAdj(score int) error {
1688 1688
 		// Setting oom_score_adj does not work in an
1689 1689
 		// unprivileged container. Ignore the error, but log
1690 1690
 		// it if we appear not to be in that situation.
1691
-		if !rsystem.RunningInUserNS() {
1691
+		if !sys.RunningInUserNS() {
1692 1692
 			logrus.Debugf("Permission denied writing %q to /proc/self/oom_score_adj", stringScore)
1693 1693
 		}
1694 1694
 		return nil
... ...
@@ -35,6 +35,7 @@ import (
35 35
 	"strings"
36 36
 	"sync"
37 37
 
38
+	"github.com/containerd/containerd/sys"
38 39
 	"github.com/docker/docker/daemon/graphdriver"
39 40
 	"github.com/docker/docker/pkg/archive"
40 41
 	"github.com/docker/docker/pkg/chrootarchive"
... ...
@@ -44,7 +45,6 @@ import (
44 44
 	"github.com/docker/docker/pkg/locker"
45 45
 	"github.com/docker/docker/pkg/system"
46 46
 	"github.com/moby/sys/mount"
47
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
48 47
 	"github.com/opencontainers/selinux/go-selinux/label"
49 48
 	"github.com/pkg/errors"
50 49
 	"github.com/sirupsen/logrus"
... ...
@@ -177,7 +177,7 @@ func supportsAufs() error {
177 177
 	// proc/filesystems for when aufs is supported
178 178
 	exec.Command("modprobe", "aufs").Run()
179 179
 
180
-	if rsystem.RunningInUserNS() {
180
+	if sys.RunningInUserNS() {
181 181
 		return ErrAufsNested
182 182
 	}
183 183
 
... ...
@@ -11,9 +11,9 @@ import (
11 11
 	"syscall"
12 12
 	"time"
13 13
 
14
+	"github.com/containerd/containerd/sys"
14 15
 	"github.com/docker/docker/pkg/pools"
15 16
 	"github.com/docker/docker/pkg/system"
16
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
17 17
 	"golang.org/x/sys/unix"
18 18
 )
19 19
 
... ...
@@ -184,7 +184,7 @@ func DirCopy(srcDir, dstDir string, copyMode Mode, copyXattrs bool) error {
184 184
 			}
185 185
 
186 186
 		case mode&os.ModeDevice != 0:
187
-			if rsystem.RunningInUserNS() {
187
+			if sys.RunningInUserNS() {
188 188
 				// cannot create a device if running in user namespace
189 189
 				return nil
190 190
 			}
... ...
@@ -14,6 +14,7 @@ import (
14 14
 	"path/filepath"
15 15
 	"strings"
16 16
 
17
+	"github.com/containerd/containerd/sys"
17 18
 	"github.com/docker/docker/daemon/graphdriver"
18 19
 	"github.com/docker/docker/daemon/graphdriver/overlayutils"
19 20
 	"github.com/docker/docker/pkg/archive"
... ...
@@ -25,7 +26,6 @@ import (
25 25
 	"github.com/docker/docker/pkg/parsers/kernel"
26 26
 	"github.com/docker/docker/pkg/system"
27 27
 	"github.com/moby/sys/mount"
28
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
29 28
 	"github.com/opencontainers/selinux/go-selinux/label"
30 29
 	"github.com/pkg/errors"
31 30
 	"github.com/sirupsen/logrus"
... ...
@@ -475,7 +475,7 @@ func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64
475 475
 		GIDMaps: d.gidMaps,
476 476
 		// Use AUFS whiteout format: https://github.com/containers/storage/blob/39a8d5ed9843844eafb5d2ba6e6a7510e0126f40/drivers/overlay/overlay.go#L1084-L1089
477 477
 		WhiteoutFormat: archive.AUFSWhiteoutFormat,
478
-		InUserNS:       rsystem.RunningInUserNS(),
478
+		InUserNS:       sys.RunningInUserNS(),
479 479
 	}); err != nil {
480 480
 		return 0, err
481 481
 	}
... ...
@@ -15,6 +15,7 @@ import (
15 15
 	"strings"
16 16
 	"sync"
17 17
 
18
+	"github.com/containerd/containerd/sys"
18 19
 	"github.com/docker/docker/daemon/graphdriver"
19 20
 	"github.com/docker/docker/daemon/graphdriver/overlayutils"
20 21
 	"github.com/docker/docker/daemon/graphdriver/quota"
... ...
@@ -29,7 +30,6 @@ import (
29 29
 	"github.com/docker/docker/pkg/system"
30 30
 	units "github.com/docker/go-units"
31 31
 	"github.com/moby/sys/mount"
32
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
33 32
 	"github.com/opencontainers/selinux/go-selinux/label"
34 33
 	"github.com/sirupsen/logrus"
35 34
 	"golang.org/x/sys/unix"
... ...
@@ -683,7 +683,7 @@ func (d *Driver) ApplyDiff(id string, parent string, diff io.Reader) (size int64
683 683
 		UIDMaps:        d.uidMaps,
684 684
 		GIDMaps:        d.gidMaps,
685 685
 		WhiteoutFormat: archive.OverlayWhiteoutFormat,
686
-		InUserNS:       rsystem.RunningInUserNS(),
686
+		InUserNS:       sys.RunningInUserNS(),
687 687
 	}); err != nil {
688 688
 		return 0, err
689 689
 	}
... ...
@@ -57,7 +57,7 @@ import (
57 57
 	"path/filepath"
58 58
 	"unsafe"
59 59
 
60
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
60
+	"github.com/containerd/containerd/sys"
61 61
 	"github.com/pkg/errors"
62 62
 	"github.com/sirupsen/logrus"
63 63
 	"golang.org/x/sys/unix"
... ...
@@ -90,7 +90,7 @@ func NewControl(basePath string) (*Control, error) {
90 90
 	// If we are running in a user namespace quota won't be supported for
91 91
 	// now since makeBackingFsDev() will try to mknod().
92 92
 	//
93
-	if rsystem.RunningInUserNS() {
93
+	if sys.RunningInUserNS() {
94 94
 		return nil, ErrQuotaNotSupported
95 95
 	}
96 96
 
... ...
@@ -14,6 +14,7 @@ import (
14 14
 
15 15
 	"github.com/containerd/containerd/containers"
16 16
 	coci "github.com/containerd/containerd/oci"
17
+	"github.com/containerd/containerd/sys"
17 18
 	containertypes "github.com/docker/docker/api/types/container"
18 19
 	"github.com/docker/docker/container"
19 20
 	daemonconfig "github.com/docker/docker/daemon/config"
... ...
@@ -28,7 +29,6 @@ import (
28 28
 	"github.com/opencontainers/runc/libcontainer/apparmor"
29 29
 	"github.com/opencontainers/runc/libcontainer/cgroups"
30 30
 	"github.com/opencontainers/runc/libcontainer/devices"
31
-	rsystem "github.com/opencontainers/runc/libcontainer/system"
32 31
 	"github.com/opencontainers/runc/libcontainer/user"
33 32
 	specs "github.com/opencontainers/runtime-spec/specs-go"
34 33
 	"github.com/pkg/errors"
... ...
@@ -857,7 +857,7 @@ func WithDevices(daemon *Daemon, c *container.Container) coci.SpecOpts {
857 857
 		var devs []specs.LinuxDevice
858 858
 		devPermissions := s.Linux.Resources.Devices
859 859
 
860
-		if c.HostConfig.Privileged && !rsystem.RunningInUserNS() {
860
+		if c.HostConfig.Privileged && !sys.RunningInUserNS() {
861 861
 			hostDevices, err := devices.HostDevices()
862 862
 			if err != nil {
863 863
 				return err