Skip to content

net/http: Server.ListenAndServeTLS() leaks TCP sockets on invalid cert or key #23002

Closed
@theckman

Description

@theckman

What version of Go are you using (go version)?

go version go1.9.2 darwin/amd64

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/theckman/go/"
GORACE=""
GOROOT="/Users/theckman/.gimme/versions/go1.9.2.darwin.amd64"
GOTOOLDIR="/Users/theckman/.gimme/versions/go1.9.2.darwin.amd64/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/f5/zjcsdkrx2bxdm32zzqfg5yp80000gn/T/go-build826228057=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"

What did you do?

What did you expect to see?

I expected the TCP socket opened by http.ListenAndServeTLS() to be closed before control was returned back to the caller.

What did you see instead?

The TCP socket was left in an open state.

If http.Server.ListenAndServeTLS() is called with either an invalid certificate or key, the function leaks the TCP socket that was opened for the server. This is because the method doesn't close the net.Listener before returning.

This is a side-effect of a difference in behaviors between http.Server.Serve() and http.Server.ServeTLS(). The non-TLS method defers a call to l.Close() to close the TCP socket before returning, the TLS version does not have this behavior implemented.

I'm not sure if the TLS method having different behavior is intentional, so I think there are two potential fixes:

  • Modify http.Server.ServeTLS() to defer a call to l.Close().
  • Avoid making behavioral changes to http.Server.ServeTLS() and instead do the defer in ListenAndServeTLS() where the TCP socket is created.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions