mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
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
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user