summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorBrian Geffon <bgeffon@google.com>2018-07-09 20:47:32 -0700
committerShentubot <shentubot@google.com>2018-07-09 20:48:27 -0700
commitda9b5153f2fafab1597b34336f8a95c1b861f0ac (patch)
tree4d9de9866368f1836424000ba09ffd39ca7c8fb9 /pkg
parent41aeb680b1882c9416e25e100b5ff5eebead36de (diff)
Fix two race conditions in tcp stack.
PiperOrigin-RevId: 203880278 Change-Id: I66b790a616de59142859cc12db4781b57ea626d3
Diffstat (limited to 'pkg')
-rw-r--r--pkg/tcpip/transport/tcp/connect.go3
-rw-r--r--pkg/tcpip/transport/tcp/endpoint.go8
2 files changed, 8 insertions, 3 deletions
diff --git a/pkg/tcpip/transport/tcp/connect.go b/pkg/tcpip/transport/tcp/connect.go
index 980663675..afdea2b53 100644
--- a/pkg/tcpip/transport/tcp/connect.go
+++ b/pkg/tcpip/transport/tcp/connect.go
@@ -949,9 +949,10 @@ func (e *endpoint) protocolMainLoop(passive bool) *tcpip.Error {
}
if n&notifyReset != 0 {
+ e.mu.Lock()
e.resetConnectionLocked(tcpip.ErrConnectionAborted)
+ e.mu.Unlock()
}
-
if n&notifyClose != 0 && closeTimer == nil {
// Reset the connection 3 seconds after the
// endpoint has been closed.
diff --git a/pkg/tcpip/transport/tcp/endpoint.go b/pkg/tcpip/transport/tcp/endpoint.go
index 9c937559c..cb105b863 100644
--- a/pkg/tcpip/transport/tcp/endpoint.go
+++ b/pkg/tcpip/transport/tcp/endpoint.go
@@ -93,6 +93,8 @@ type endpoint struct {
//
// Once the peer has closed its send side, rcvClosed is set to true
// to indicate to users that no more data is coming.
+ //
+ // rcvListMu can be taken after the endpoint mu below.
rcvListMu sync.Mutex `state:"nosave"`
rcvList segmentList
rcvClosed bool
@@ -394,7 +396,10 @@ func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.ControlMessages,
// but has some pending unread data. Also note that a RST being received
// would cause the state to become stateError so we should allow the
// reads to proceed before returning a ECONNRESET.
- if s := e.state; s != stateConnected && s != stateClosed && e.rcvBufUsed == 0 {
+ e.rcvListMu.Lock()
+ bufUsed := e.rcvBufUsed
+ if s := e.state; s != stateConnected && s != stateClosed && bufUsed == 0 {
+ e.rcvListMu.Unlock()
e.mu.RUnlock()
if s == stateError {
return buffer.View{}, tcpip.ControlMessages{}, e.hardError
@@ -402,7 +407,6 @@ func (e *endpoint) Read(*tcpip.FullAddress) (buffer.View, tcpip.ControlMessages,
return buffer.View{}, tcpip.ControlMessages{}, tcpip.ErrInvalidEndpointState
}
- e.rcvListMu.Lock()
v, err := e.readLocked()
e.rcvListMu.Unlock()