From 0caa2d3992606370fa78eaa87213e14528288e02 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 6 Mar 2014 14:10:32 +0100 Subject: [PATCH] libcontainer: Don't use UsetCloseOnExec, it is racy We can't keep file descriptors without close-on-exec except with syscall.ForkLock held, as otherwise they could leak by accident into other children from forks in other threads. Instead we just use Cmd.ExtraFiles which handles all this for us. This fixes https://github.com/dotcloud/docker/issues/4493 Docker-DCO-1.1-Signed-off-by: Alexander Larsson (github: alexlarsson) --- libcontainer/nsinit/command.go | 8 ++++---- libcontainer/nsinit/exec.go | 2 +- libcontainer/nsinit/sync_pipe.go | 2 -- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libcontainer/nsinit/command.go b/libcontainer/nsinit/command.go index 8ddf1e7..5546065 100644 --- a/libcontainer/nsinit/command.go +++ b/libcontainer/nsinit/command.go @@ -1,7 +1,6 @@ package nsinit import ( - "fmt" "github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/system" "os" @@ -12,7 +11,7 @@ import ( // parent processes and creates an *exec.Cmd that will be used to fork/exec the // namespaced init process type CommandFactory interface { - Create(container *libcontainer.Container, console string, syncFd uintptr, args []string) *exec.Cmd + Create(container *libcontainer.Container, console string, syncFd *os.File, args []string) *exec.Cmd } type DefaultCommandFactory struct { @@ -22,16 +21,17 @@ type DefaultCommandFactory struct { // Create will return an exec.Cmd with the Cloneflags set to the proper namespaces // defined on the container's configuration and use the current binary as the init with the // args provided -func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe uintptr, args []string) *exec.Cmd { +func (c *DefaultCommandFactory) Create(container *libcontainer.Container, console string, pipe *os.File, args []string) *exec.Cmd { // get our binary name from arg0 so we can always reexec ourself command := exec.Command(os.Args[0], append([]string{ "-console", console, - "-pipe", fmt.Sprint(pipe), + "-pipe", "3", "-root", c.Root, "init"}, args...)...) system.SetCloneFlags(command, uintptr(GetNamespaceFlags(container.Namespaces))) command.Env = container.Env + command.ExtraFiles = []*os.File{pipe} return command } diff --git a/libcontainer/nsinit/exec.go b/libcontainer/nsinit/exec.go index f1a4e24..4963f12 100644 --- a/libcontainer/nsinit/exec.go +++ b/libcontainer/nsinit/exec.go @@ -35,7 +35,7 @@ func (ns *linuxNs) Exec(container *libcontainer.Container, term Terminal, args [ term.SetMaster(master) } - command := ns.commandFactory.Create(container, console, syncPipe.child.Fd(), args) + command := ns.commandFactory.Create(container, console, syncPipe.child, args) if err := term.Attach(command); err != nil { return -1, err } diff --git a/libcontainer/nsinit/sync_pipe.go b/libcontainer/nsinit/sync_pipe.go index 7b29e98..f724f52 100644 --- a/libcontainer/nsinit/sync_pipe.go +++ b/libcontainer/nsinit/sync_pipe.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "github.com/dotcloud/docker/pkg/libcontainer" - "github.com/dotcloud/docker/pkg/system" "io/ioutil" "os" ) @@ -22,7 +21,6 @@ func NewSyncPipe() (s *SyncPipe, err error) { if err != nil { return nil, err } - system.UsetCloseOnExec(s.child.Fd()) return s, nil }