summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2019-10-10 23:59:30 +0000
committergVisor bot <gvisor-bot@google.com>2019-10-10 23:59:30 +0000
commit61d88df862dcb5540e347cc761ae7ca7ba85d2d4 (patch)
tree36d409402f5552de946f6a8ac9328fbda4fd94ac /pkg/sentry
parenta738d4999a26215ac154a4144591a23ca1dd2865 (diff)
parent470997ca9990f2a985b7c29f5f27dc56b5fbec32 (diff)
Merge release-20190806.1-263-g470997c (automated)
Diffstat (limited to 'pkg/sentry')
-rw-r--r--pkg/sentry/socket/netlink/socket.go22
1 files changed, 22 insertions, 0 deletions
diff --git a/pkg/sentry/socket/netlink/socket.go b/pkg/sentry/socket/netlink/socket.go
index d0aab293d..b2732ca29 100644
--- a/pkg/sentry/socket/netlink/socket.go
+++ b/pkg/sentry/socket/netlink/socket.go
@@ -28,6 +28,7 @@ import (
"gvisor.dev/gvisor/pkg/sentry/fs/fsutil"
"gvisor.dev/gvisor/pkg/sentry/kernel"
ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time"
+ "gvisor.dev/gvisor/pkg/sentry/safemem"
"gvisor.dev/gvisor/pkg/sentry/socket"
"gvisor.dev/gvisor/pkg/sentry/socket/netlink/port"
"gvisor.dev/gvisor/pkg/sentry/socket/unix"
@@ -416,6 +417,24 @@ func (s *Socket) RecvMsg(t *kernel.Task, dst usermem.IOSequence, flags int, have
Peek: flags&linux.MSG_PEEK != 0,
}
+ // If MSG_TRUNC is set with a zero byte destination then we still need
+ // to read the message and discard it, or in the case where MSG_PEEK is
+ // set, leave it be. In both cases the full message length must be
+ // returned. However, the memory manager for the destination will not read
+ // the endpoint if the destination is zero length.
+ //
+ // In order for the endpoint to be read when the destination size is zero,
+ // we must cause a read of the endpoint by using a separate fake zero
+ // length block sequence and calling the EndpointReader directly.
+ if trunc && dst.Addrs.NumBytes() == 0 {
+ // Perform a read to a zero byte block sequence. We can ignore the
+ // original destination since it was zero bytes. The length returned by
+ // ReadToBlocks is ignored and we return the full message length to comply
+ // with MSG_TRUNC.
+ _, err := r.ReadToBlocks(safemem.BlockSeqOf(safemem.BlockFromSafeSlice(make([]byte, 0))))
+ return int(r.MsgSize), linux.MSG_TRUNC, from, fromLen, socket.ControlMessages{}, syserr.FromError(err)
+ }
+
if n, err := dst.CopyOutFrom(t, &r); err != syserror.ErrWouldBlock || flags&linux.MSG_DONTWAIT != 0 {
var mflags int
if n < int64(r.MsgSize) {
@@ -499,6 +518,9 @@ func (s *Socket) sendResponse(ctx context.Context, ms *MessageSet) *syserr.Error
PortID: uint32(ms.PortID),
})
+ // Add the dump_done_errno payload.
+ m.Put(int64(0))
+
_, notify, err := s.connection.Send([][]byte{m.Finalize()}, transport.ControlMessages{}, tcpip.FullAddress{})
if err != nil && err != syserr.ErrWouldBlock {
return err