From 23f49097c77213175e9b11755c28c3ff5ccc1118 Mon Sep 17 00:00:00 2001 From: Brian Geffon Date: Fri, 29 Jun 2018 12:39:22 -0700 Subject: Panic in netstack during cleanup where a FIN becomes a RST. There is a subtle bug where during cleanup with unread data a FIN can be converted to a RST, at that point the entire connection should be aborted as we're not expecting any ACKs to the RST. PiperOrigin-RevId: 202691271 Change-Id: Idae70800208ca26e07a379bc6b2b8090805d0a22 --- pkg/tcpip/transport/tcp/endpoint.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'pkg/tcpip/transport/tcp/endpoint.go') diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go index b21c2b4ab..191dc1acc 100644 --- a/pkg/tcpip/transport/tcp/endpoint.go +++ b/pkg/tcpip/transport/tcp/endpoint.go @@ -40,6 +40,7 @@ const ( notifyClose notifyMTUChanged notifyDrain + notifyReset ) // SACKInfo holds TCP SACK related information for a given endpoint. @@ -919,7 +920,20 @@ func (e *endpoint) Shutdown(flags tcpip.ShutdownFlags) *tcpip.Error { switch e.state { case stateConnected: // Close for write. - if (flags & tcpip.ShutdownWrite) != 0 { + if (e.shutdownFlags & tcpip.ShutdownWrite) != 0 { + if (e.shutdownFlags & tcpip.ShutdownRead) != 0 { + // We're fully closed, if we have unread data we need to abort + // the connection with a RST. + e.rcvListMu.Lock() + rcvBufUsed := e.rcvBufUsed + e.rcvListMu.Unlock() + + if rcvBufUsed > 0 { + e.notifyProtocolGoroutine(notifyReset) + return nil + } + } + e.sndBufMu.Lock() if e.sndClosed { -- cgit v1.2.3