summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry
diff options
context:
space:
mode:
authorBrian Geffon <bgeffon@google.com>2018-05-24 15:17:42 -0700
committerShentubot <shentubot@google.com>2018-05-24 15:18:21 -0700
commit7f62e9c32ea6af19ccd92107252fd869e6ef1005 (patch)
tree00fab3faeb7dbb2b689247157f8be0767e128758 /pkg/sentry
parente48f7078761b00552ac74068c184ee4fb90fe9aa (diff)
rpcinet connect doesn't handle all errnos correctly.
These were causing non-blocking related errnos to be returned to the sentry when they were created as blocking FDs internally. PiperOrigin-RevId: 197962932 Change-Id: I3f843535ff87ebf4cb5827e9f3d26abfb79461b0
Diffstat (limited to 'pkg/sentry')
-rw-r--r--pkg/sentry/socket/rpcinet/socket.go22
1 files changed, 10 insertions, 12 deletions
diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go
index 11925f8d8..bca91ab5f 100644
--- a/pkg/sentry/socket/rpcinet/socket.go
+++ b/pkg/sentry/socket/rpcinet/socket.go
@@ -213,21 +213,19 @@ func (s *socketOperations) Connect(t *kernel.Task, sockaddr []byte, blocking boo
// Register for notification when the endpoint becomes writable, then
// initiate the connection.
e, ch := waiter.NewChannelEntry(nil)
- s.EventRegister(&e, waiter.EventOut)
+ s.EventRegister(&e, waiter.EventOut|waiter.EventIn|waiter.EventHUp)
defer s.EventUnregister(&e)
+ for {
+ if err := rpcConnect(t, s.fd, sockaddr); err == nil || err != syserr.ErrInProgress && err != syserr.ErrAlreadyInProgress {
+ return err
+ }
- if err := rpcConnect(t, s.fd, sockaddr); err != syserr.ErrConnectStarted && err != syserr.ErrAlreadyConnecting {
- return err
- }
-
- // It's pending, so we have to wait for a notification, and fetch the
- // result once the wait completes.
- if err := t.Block(ch); err != nil {
- return syserr.FromError(err)
+ // It's pending, so we have to wait for a notification, and fetch the
+ // result once the wait completes.
+ if err := t.Block(ch); err != nil {
+ return syserr.FromError(err)
+ }
}
-
- // Call Connect() again after blocking to find connect's result.
- return rpcConnect(t, s.fd, sockaddr)
}
func rpcAccept(t *kernel.Task, fd uint32, peer bool) (*pb.AcceptResponse_ResultPayload, *syserr.Error) {