diff options
author | Andrei Vagin <avagin@google.com> | 2021-09-02 15:13:45 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-09-02 15:15:45 -0700 |
commit | 9149b2cefdb5883e41416aecea16fba4c5cd3ac1 (patch) | |
tree | 14c670ea42c8d0e791d8808baf3cf3080db82c3a | |
parent | bd75e52ad87d6a2fa70d7e0e0871376e59677690 (diff) |
unix: avoid taking two endpoint locks
If we want to take two endpoint locks, we need to be sure that we always
take them in the same order.
Accept() locks the listening endpoint to work with acceptedChan and then
it calls GetLocalAddress that locks an accepted endpoint. Actually, we
can release the listening endpoint lock before calling GetLocalAddress.
Reported-by: syzbot+f52bd603f51a4ae91054@syzkaller.appspotmail.com
PiperOrigin-RevId: 394553823
-rw-r--r-- | pkg/sentry/socket/unix/transport/connectioned.go | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/pkg/sentry/socket/unix/transport/connectioned.go b/pkg/sentry/socket/unix/transport/connectioned.go index 9a398c3b5..b3f0cf563 100644 --- a/pkg/sentry/socket/unix/transport/connectioned.go +++ b/pkg/sentry/socket/unix/transport/connectioned.go @@ -406,14 +406,15 @@ func (e *connectionedEndpoint) Listen(backlog int) *syserr.Error { // Accept accepts a new connection. func (e *connectionedEndpoint) Accept(peerAddr *tcpip.FullAddress) (Endpoint, *syserr.Error) { e.Lock() - defer e.Unlock() if !e.Listening() { + e.Unlock() return nil, syserr.ErrInvalidEndpointState } select { case ne := <-e.acceptedChan: + e.Unlock() if peerAddr != nil { ne.Lock() c := ne.connected @@ -429,6 +430,7 @@ func (e *connectionedEndpoint) Accept(peerAddr *tcpip.FullAddress) (Endpoint, *s return ne, nil default: + e.Unlock() // Nothing left. return nil, syserr.ErrWouldBlock } |