aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSébastien Paolacci <sebastien.paolacci@gmail.com>2012-09-22 05:55:01 +1000
committerBrad Fitzpatrick <bradfitz@golang.org>2012-09-22 05:55:01 +1000
commit0d1bbdf52ea7e957d2d22c5c22f2ab71bc598a17 (patch)
treee2bca00d074ca5496fef390c819bfddff3f00a0a
parentc57119f04cf84e09e3038942dc40934a8f88a29d (diff)
downloadgo-0d1bbdf52ea7e957d2d22c5c22f2ab71bc598a17.tar.gz
go-0d1bbdf52ea7e957d2d22c5c22f2ab71bc598a17.zip
[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 »»»
-rw-r--r--src/pkg/net/file.go4
-rw-r--r--src/pkg/os/exec/exec_test.go12
2 files changed, 16 insertions, 0 deletions
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) {