summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorBhasker Hariharan <bhaskerh@google.com>2021-02-26 20:14:34 -0800
committergVisor bot <gvisor-bot@google.com>2021-02-26 20:16:48 -0800
commit037bb2f45abada02fb50b563f3d37381f88de7f5 (patch)
treeb005d16f3275e7c0253a4bbf9269072db6656d71 /pkg
parentaf6e6d5e7fc8266016eefa309d3857c92102db9a (diff)
Fix panic due to zero length writes in TCP.
There is a short race where in Write an endpoint can transition from writable to non-writable state due to say an incoming RST during the time we release the endpoint lock and reacquire after copying the payload. In such a case if the write happens to be a zero sized write we end up trying to call sendData() even though nothing was queued. This can panic when trying to enable/disable TCP timers if the endpoint had already transitioned to a CLOSED/ERROR state due to the incoming RST as we cleanup timers when the protocol goroutine terminates. Sadly the race window is small enough that my attempts at reproducing the panic in a syscall test has not been successful. PiperOrigin-RevId: 359887905
Diffstat (limited to 'pkg')
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go4
1 files changed, 3 insertions, 1 deletions
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go
index 8c5be0586..83ec99fa9 100644
--- a/pkg/tcpip/transport/tcp/endpoint.go
+++ b/pkg/tcpip/transport/tcp/endpoint.go
@@ -1586,7 +1586,9 @@ func (e *endpoint) Write(p tcpip.Payloader, opts tcpip.WriteOptions) (int64, tcp
return e.drainSendQueueLocked(), len(v), nil
}()
- if err != nil {
+ // Return if either we didn't queue anything or if an error occurred while
+ // attempting to queue data.
+ if n == 0 || err != nil {
return 0, err
}
e.sendData(nextSeg)