From 9dfcd8b09fceff830c880065db66821e53c500b0 Mon Sep 17 00:00:00 2001 From: Ian Gudger Date: Mon, 9 Sep 2019 14:00:51 -0700 Subject: Fix ephemeral port leak. Fix a bug where udp.(*endpoint).Disconnect [accessible in gVisor via epsocket.(*SocketOperations).Connect with AF_UNSPEC] would leak a port reservation if the socket/endpoint had an ephemeral port assigned to it. glibc's getaddrinfo uses connect with AF_UNSPEC, causing each call of getaddrinfo to leak a port. Call getaddrinfo too many times and you run out of ports (shows up as connect returning EAGAIN and getaddrinfo returning EAI_NONAME "Name or service not known"). PiperOrigin-RevId: 268071160 --- pkg/tcpip/transport/udp/endpoint.go | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'pkg/tcpip/transport') diff --git a/pkg/tcpip/transport/udp/endpoint.go b/pkg/tcpip/transport/udp/endpoint.go index 66455ef46..dccb9a7eb 100644 --- a/pkg/tcpip/transport/udp/endpoint.go +++ b/pkg/tcpip/transport/udp/endpoint.go @@ -747,6 +747,10 @@ func (e *endpoint) Disconnect() *tcpip.Error { } e.state = StateBound } else { + if e.id.LocalPort != 0 { + // Release the ephemeral port. + e.stack.ReleasePort(e.effectiveNetProtos, ProtocolNumber, e.id.LocalAddress, e.id.LocalPort) + } e.state = StateInitial } -- cgit v1.2.3