From 40b9b89107eef4b4b847edf5717a7b48b3c2a451 Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Wed, 15 Jul 2015 10:41:25 -0700 Subject: [PATCH 1/2] Substract bindmount path from cgroup dir Signed-off-by: Alexander Morozov --- libcontainer/cgroups/utils.go | 3 ++- libcontainer/rootfs_linux.go | 10 +++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libcontainer/cgroups/utils.go b/libcontainer/cgroups/utils.go index 8ab80a7f..c97dab02 100644 --- a/libcontainer/cgroups/utils.go +++ b/libcontainer/cgroups/utils.go @@ -57,6 +57,7 @@ func FindCgroupMountpointDir() (string, error) { type Mount struct { Mountpoint string + Root string Subsystems []string } @@ -87,7 +88,7 @@ func GetCgroupMounts() ([]Mount, error) { res := []Mount{} for _, mount := range mounts { if mount.Fstype == "cgroup" { - m := Mount{Mountpoint: mount.Mountpoint} + m := Mount{Mountpoint: mount.Mountpoint, Root: mount.Root} for _, opt := range strings.Split(mount.VfsOpts, ",") { if strings.HasPrefix(opt, "name=") { diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 8a9e38a2..a211d8de 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -180,18 +180,22 @@ func mountToRootfs(m *configs.Mount, rootfs, mountLabel string) error { if err != nil { return err } + relDir, err := filepath.Rel(mm.Root, dir) + if err != nil { + return err + } binds = append(binds, &configs.Mount{ Device: "bind", - Source: filepath.Join(mm.Mountpoint, dir), + Source: filepath.Join(mm.Mountpoint, relDir), Destination: filepath.Join(m.Destination, strings.Join(mm.Subsystems, ",")), Flags: syscall.MS_BIND | syscall.MS_REC | m.Flags, }) } tmpfs := &configs.Mount{ - Device: "tmpfs", Source: "tmpfs", + Device: "tmpfs", Destination: m.Destination, - Flags: syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV, + Flags: defaultMountFlags, } if err := mountToRootfs(tmpfs, rootfs, mountLabel); err != nil { return err From f6eb19c0d5fce32824eefaee5835bdd713a39afe Mon Sep 17 00:00:00 2001 From: Alexander Morozov Date: Wed, 15 Jul 2015 11:07:03 -0700 Subject: [PATCH 2/2] Tests for mounting cgroups Signed-off-by: Alexander Morozov --- libcontainer/integration/exec_test.go | 69 +++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go index 88118638..ae7ecc41 100644 --- a/libcontainer/integration/exec_test.go +++ b/libcontainer/integration/exec_test.go @@ -819,3 +819,72 @@ func TestSeccompNoChown(t *testing.T) { t.Fatalf("running chown should result in an EPERM but got %q", s) } } + +func TestMountCgroupRO(t *testing.T) { + if testing.Short() { + return + } + rootfs, err := newRootfs() + ok(t, err) + defer remove(rootfs) + config := newTemplateConfig(rootfs) + + config.Mounts = append(config.Mounts, &configs.Mount{ + Destination: "/sys/fs/cgroup", + Device: "cgroup", + Flags: defaultMountFlags | syscall.MS_RDONLY, + }) + + buffers, exitCode, err := runContainer(config, "", "mount") + if err != nil { + t.Fatalf("%s: %s", buffers, err) + } + if exitCode != 0 { + t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr) + } + mountInfo := buffers.Stdout.String() + lines := strings.Split(mountInfo, "\n") + for _, l := range lines { + if !strings.HasPrefix(l, "cgroup") { + continue + } + if !strings.Contains(l, "ro,nosuid,nodev,noexec") { + t.Fatalf("Mode expected to contain 'ro,nosuid,nodev,noexec': %s", l) + } + } +} + +func TestMountCgroupRW(t *testing.T) { + t.Skip("This test is screwed because of dind") + if testing.Short() { + return + } + rootfs, err := newRootfs() + ok(t, err) + defer remove(rootfs) + config := newTemplateConfig(rootfs) + + config.Mounts = append(config.Mounts, &configs.Mount{ + Destination: "/sys/fs/cgroup", + Device: "cgroup", + Flags: defaultMountFlags, + }) + + buffers, exitCode, err := runContainer(config, "", "mount") + if err != nil { + t.Fatalf("%s: %s", buffers, err) + } + if exitCode != 0 { + t.Fatalf("exit code not 0. code %d stderr %q", exitCode, buffers.Stderr) + } + mountInfo := buffers.Stdout.String() + lines := strings.Split(mountInfo, "\n") + for _, l := range lines { + if !strings.HasPrefix(l, "cgroup") { + continue + } + if !strings.Contains(l, "rw,nosuid,nodev,noexec") { + t.Fatalf("Mode expected to contain 'rw,nosuid,nodev,noexec': %s", l) + } + } +}