diff options
author | Brian Geffon <bgeffon@google.com> | 2018-11-27 17:47:16 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2018-11-27 17:48:05 -0800 |
commit | 5bd02b224fd0eb81fc028644137a24d0bbf7dab5 (patch) | |
tree | 995116d6614fe807f081832291f784dff4de2913 | |
parent | 9e0f13237793897c805f75af163006049b37e784 (diff) |
Save shutdown flags first.
With rpcinet if shutdown flags are not saved before making
the rpc a race is possible where blocked threads are woken
up before the flags have been persisted. This would mean
that threads can block indefinitely in a recvmsg after a
shutdown(SHUT_RD) has happened.
PiperOrigin-RevId: 223089783
Change-Id: If595e7add12aece54bcdf668ab64c570910d061a
-rw-r--r-- | pkg/sentry/socket/rpcinet/socket.go | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go index 788d853c9..7328661ab 100644 --- a/pkg/sentry/socket/rpcinet/socket.go +++ b/pkg/sentry/socket/rpcinet/socket.go @@ -354,6 +354,13 @@ func (s *socketOperations) Listen(t *kernel.Task, backlog int) *syserr.Error { // Shutdown implements socket.Socket.Shutdown. func (s *socketOperations) Shutdown(t *kernel.Task, how int) *syserr.Error { + // We save the shutdown state because of strange differences on linux + // related to recvs on blocking vs. non-blocking sockets after a SHUT_RD. + // We need to emulate that behavior on the blocking side. + // TODO: There is a possible race that can exist with loopback, + // where data could possibly be lost. + s.setShutdownFlags(how) + stack := t.NetworkContext().(*Stack) id, c := stack.rpcConn.NewRequest(pb.SyscallRequest{Args: &pb.SyscallRequest_Shutdown{&pb.ShutdownRequest{Fd: s.fd, How: int64(how)}}}, false /* ignoreResult */) <-c @@ -362,10 +369,6 @@ func (s *socketOperations) Shutdown(t *kernel.Task, how int) *syserr.Error { return syserr.FromHost(syscall.Errno(e)) } - // We save the shutdown state because of strange differences on linux - // related to recvs on blocking vs. non-blocking sockets after a SHUT_RD. - // We need to emulate that behavior on the blocking side. - s.setShutdownFlags(how) return nil } |