diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 7acfc1f0419..4aa4cbd5ef2 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 a3bb07708b9..f70e10bebe0 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") + } +}