From 42234a85d1f73163362c3259f770785308aa5f1d Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Fri, 8 Apr 2016 05:01:39 +0000 Subject: [PATCH] Fix setupDev logic in rootfs_linux.go setupDev was introduced in #96, but broken since #536 because spec 0.3.0 introduced default devices. Fix #80 again Fix docker/docker#21808 Signed-off-by: Akihiro Suda Signed-off-by: Alexander Morozov --- libcontainer/rootfs_linux.go | 12 +++++- libcontainer/rootfs_linux_test.go | 66 ++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 2 deletions(-) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 7acfc1f0..4aa4cbd5 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -25,6 +25,16 @@ import ( const defaultMountFlags = syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV +// setupDev returns true if /dev needs to be set up. +func needsSetupDev(config *configs.Config) bool { + for _, m := range config.Mounts { + if m.Device == "bind" && (m.Destination == "/dev" || m.Destination == "/dev/") { + return false + } + } + return true +} + // setupRootfs sets up the devices, mount points, and filesystems for use inside a // new mount namespace. func setupRootfs(config *configs.Config, console *linuxConsole, pipe io.ReadWriter) (err error) { @@ -32,7 +42,7 @@ func setupRootfs(config *configs.Config, console *linuxConsole, pipe io.ReadWrit return newSystemError(err) } - setupDev := len(config.Devices) != 0 + setupDev := needsSetupDev(config) for _, m := range config.Mounts { for _, precmd := range m.PremountCmds { if err := mountCmd(precmd); err != nil { diff --git a/libcontainer/rootfs_linux_test.go b/libcontainer/rootfs_linux_test.go index a3bb0770..f70e10be 100644 --- a/libcontainer/rootfs_linux_test.go +++ b/libcontainer/rootfs_linux_test.go @@ -2,7 +2,11 @@ package libcontainer -import "testing" +import ( + "testing" + + "github.com/opencontainers/runc/libcontainer/configs" +) func TestCheckMountDestOnProc(t *testing.T) { dest := "/rootfs/proc/" @@ -35,3 +39,63 @@ func TestCheckMountRoot(t *testing.T) { t.Fatal(err) } } + +func TestNeedsSetupDev(t *testing.T) { + config := &configs.Config{ + Mounts: []*configs.Mount{ + { + Device: "bind", + Source: "/dev", + Destination: "/dev", + }, + }, + } + if needsSetupDev(config) { + t.Fatal("expected needsSetupDev to be false, got true") + } +} + +func TestNeedsSetupDevStrangeSource(t *testing.T) { + config := &configs.Config{ + Mounts: []*configs.Mount{ + { + Device: "bind", + Source: "/devx", + Destination: "/dev", + }, + }, + } + if needsSetupDev(config) { + t.Fatal("expected needsSetupDev to be false, got true") + } +} + +func TestNeedsSetupDevStrangeDest(t *testing.T) { + config := &configs.Config{ + Mounts: []*configs.Mount{ + { + Device: "bind", + Source: "/dev", + Destination: "/devx", + }, + }, + } + if !needsSetupDev(config) { + t.Fatal("expected needsSetupDev to be true, got false") + } +} + +func TestNeedsSetupDevStrangeSourceDest(t *testing.T) { + config := &configs.Config{ + Mounts: []*configs.Mount{ + { + Device: "bind", + Source: "/devx", + Destination: "/devx", + }, + }, + } + if !needsSetupDev(config) { + t.Fatal("expected needsSetupDev to be true, got false") + } +}