summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorBrian Geffon <bgeffon@google.com>2018-06-11 16:39:39 -0700
committerShentubot <shentubot@google.com>2018-06-11 16:40:38 -0700
commitab2c2575d61266725ce13dff570663464a171342 (patch)
tree619eb5019fe4ea98d47254c9c419368bb57a5857
parent0412f17e06670fb1f1d1d85ddd73bbadde40c087 (diff)
Rpcinet is incorrectly handling MSG_TRUNC with SOCK_STREAM
SOCK_STREAM has special behavior with respect to MSG_TRUNC. Specifically, the data isn't actually copied back out to userspace when MSG_TRUNC is provided on a SOCK_STREAM. According to tcp(7): "Since version 2.4, Linux supports the use of MSG_TRUNC in the flags argument of recv(2) (and recvmsg(2)). This flag causes the received bytes of data to be discarded, rather than passed back in a caller-supplied buffer." PiperOrigin-RevId: 200134860 Change-Id: I70f17a5f60ffe7794c3f0cfafd131c069202e90d
-rw-r--r--pkg/sentry/socket/rpcinet/socket.go20
1 files changed, 14 insertions, 6 deletions
diff --git a/pkg/sentry/socket/rpcinet/socket.go b/pkg/sentry/socket/rpcinet/socket.go
index ffe947500..6f1a4fe01 100644
--- a/pkg/sentry/socket/rpcinet/socket.go
+++ b/pkg/sentry/socket/rpcinet/socket.go
@@ -465,9 +465,13 @@ func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags
res, err := rpcRecvMsg(t, req)
if err == nil {
- n, e := dst.CopyOut(t, res.Data)
- if e == nil && n != len(res.Data) {
- panic("CopyOut failed to copy full buffer")
+ var e error
+ var n int
+ if len(res.Data) > 0 {
+ n, e = dst.CopyOut(t, res.Data)
+ if e == nil && n != len(res.Data) {
+ panic("CopyOut failed to copy full buffer")
+ }
}
return int(res.Length), res.Address.GetAddress(), res.Address.GetLength(), socket.ControlMessages{}, syserr.FromError(e)
}
@@ -484,9 +488,13 @@ func (s *socketOperations) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags
for {
res, err := rpcRecvMsg(t, req)
if err == nil {
- n, e := dst.CopyOut(t, res.Data)
- if e == nil && n != len(res.Data) {
- panic("CopyOut failed to copy full buffer")
+ var e error
+ var n int
+ if len(res.Data) > 0 {
+ n, e = dst.CopyOut(t, res.Data)
+ if e == nil && n != len(res.Data) {
+ panic("CopyOut failed to copy full buffer")
+ }
}
return int(res.Length), res.Address.GetAddress(), res.Address.GetLength(), socket.ControlMessages{}, syserr.FromError(e)
}