diff options
author | Bhasker Hariharan <bhaskerh@google.com> | 2020-11-17 08:30:31 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-11-17 08:33:03 -0800 |
commit | fb9a649f39dc6f6a6accbf26db30a21fcc4bcf23 (patch) | |
tree | fce01911bb8d060762bda4a58bc5ad2b0a0d2d0c /pkg/sentry | |
parent | 938aabeecb935771ab5be5eca5acff0bd19ebc97 (diff) |
Fix SO_ERROR behavior for TCP in gVisor.
Fixes the behaviour of SO_ERROR for tcp sockets where in linux it returns
sk->sk_err and if sk->sk_err is 0 then it returns sk->sk_soft_err. In gVisor TCP
we endpoint.HardError is the equivalent of sk->sk_err and endpoint.LastError
holds soft errors. This change brings this into alignment with Linux such that
both hard/soft errors are cleared when retrieved using getsockopt(.. SO_ERROR)
is called on a socket.
Fixes #3812
PiperOrigin-RevId: 342868552
Diffstat (limited to 'pkg/sentry')
-rw-r--r-- | pkg/sentry/socket/netstack/netstack.go | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/pkg/sentry/socket/netstack/netstack.go b/pkg/sentry/socket/netstack/netstack.go index 7d0ae15ca..5afe77858 100644 --- a/pkg/sentry/socket/netstack/netstack.go +++ b/pkg/sentry/socket/netstack/netstack.go @@ -2686,7 +2686,7 @@ func (s *socketOpsCommon) coalescingRead(ctx context.Context, dst usermem.IOSequ // Always do at least one fetchReadView, even if the number of bytes to // read is 0. err = s.fetchReadView() - if err != nil { + if err != nil || len(s.readView) == 0 { break } if dst.NumBytes() == 0 { @@ -2709,15 +2709,20 @@ func (s *socketOpsCommon) coalescingRead(ctx context.Context, dst usermem.IOSequ } copied += n s.readView.TrimFront(n) - if len(s.readView) == 0 { - atomic.StoreUint32(&s.readViewHasData, 0) - } dst = dst.DropFirst(n) if e != nil { err = syserr.FromError(e) break } + // If we are done reading requested data then stop. + if dst.NumBytes() == 0 { + break + } + } + + if len(s.readView) == 0 { + atomic.StoreUint32(&s.readViewHasData, 0) } // If we managed to copy something, we must deliver it. |