From: Sébastien Paolacci Date: Fri, 21 Sep 2012 19:55:01 +0000 (+1000) Subject: [release-branch.go1] net: fix {FileConn, FileListener, FilePacketConn} fd leak to... X-Git-Tag: go1.0.3~41 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0d1bbdf52ea7e957d2d22c5c22f2ab71bc598a17;p=gostls13.git [release-branch.go1] net: fix {FileConn, FileListener, FilePacketConn} fd leak to child process. ««« backport d694b1866058 net: fix {FileConn, FileListener, FilePacketConn} fd leak to child process. All of them call `newFileFD' which must properly restore close-on-exec on duplicated fds. R=golang-dev, bradfitz, mikioh.mikioh CC=golang-dev https://golang.org/cl/6445081 »»» --- diff --git a/src/pkg/net/file.go b/src/pkg/net/file.go index 1abf24f2d6..837326e12e 100644 --- a/src/pkg/net/file.go +++ b/src/pkg/net/file.go @@ -12,10 +12,14 @@ import ( ) func newFileFD(f *os.File) (*netFD, error) { + syscall.ForkLock.RLock() fd, err := syscall.Dup(int(f.Fd())) if err != nil { + syscall.ForkLock.RUnlock() return nil, os.NewSyscallError("dup", err) } + syscall.CloseOnExec(fd) + syscall.ForkLock.RUnlock() sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE) if err != nil { diff --git a/src/pkg/os/exec/exec_test.go b/src/pkg/os/exec/exec_test.go index aead57d799..27ebb60d3d 100644 --- a/src/pkg/os/exec/exec_test.go +++ b/src/pkg/os/exec/exec_test.go @@ -167,6 +167,18 @@ func TestExtraFiles(t *testing.T) { } defer ln.Close() + // Make sure duplicated fds don't leak to the child. + f, err := ln.(*net.TCPListener).File() + if err != nil { + t.Fatal(err) + } + defer f.Close() + ln2, err := net.FileListener(f) + if err != nil { + t.Fatal(err) + } + defer ln2.Close() + // Force TLS root certs to be loaded (which might involve // cgo), to make sure none of that potential C code leaks fds. ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {