summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@google.com>2021-09-02 15:13:45 -0700
committergVisor bot <gvisor-bot@google.com>2021-09-02 15:15:45 -0700
commit9149b2cefdb5883e41416aecea16fba4c5cd3ac1 (patch)
tree14c670ea42c8d0e791d8808baf3cf3080db82c3a
parentbd75e52ad87d6a2fa70d7e0e0871376e59677690 (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.go4
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
}