summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrei Vagin <avagin@google.com>2021-02-22 11:37:13 -0800
committergVisor bot <gvisor-bot@google.com>2021-02-22 11:51:30 -0800
commitc5a4e100085ccbd063df36706cccf93951439cb7 (patch)
treef97c68b9043fec0c37df46a94b8bf1e79fc22422
parent19fe3a2bfb72622c307311dc61019238896a756b (diff)
unix: sendmmsg and recvmsg have to cap a number of message to UIO_MAXIOV
Reported-by: syzbot+f2489ba0b999a45d1ad1@syzkaller.appspotmail.com PiperOrigin-RevId: 358866218
-rw-r--r--pkg/sentry/syscalls/linux/sys_socket.go8
-rw-r--r--pkg/sentry/syscalls/linux/vfs2/socket.go8
-rw-r--r--test/syscalls/linux/BUILD2
-rw-r--r--test/syscalls/linux/socket_generic_test_cases.cc (renamed from test/syscalls/linux/socket_generic.cc)21
4 files changed, 38 insertions, 1 deletions
diff --git a/pkg/sentry/syscalls/linux/sys_socket.go b/pkg/sentry/syscalls/linux/sys_socket.go
index 686392cc8..c6adfe06b 100644
--- a/pkg/sentry/syscalls/linux/sys_socket.go
+++ b/pkg/sentry/syscalls/linux/sys_socket.go
@@ -657,6 +657,10 @@ func RecvMMsg(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
return 0, nil, syserror.EINVAL
}
+ if vlen > linux.UIO_MAXIOV {
+ vlen = linux.UIO_MAXIOV
+ }
+
// Reject flags that we don't handle yet.
if flags & ^(baseRecvFlags|linux.MSG_CMSG_CLOEXEC|linux.MSG_ERRQUEUE) != 0 {
return 0, nil, syserror.EINVAL
@@ -938,6 +942,10 @@ func SendMMsg(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
return 0, nil, syserror.EINVAL
}
+ if vlen > linux.UIO_MAXIOV {
+ vlen = linux.UIO_MAXIOV
+ }
+
// Get socket from the file descriptor.
file := t.GetFile(fd)
if file == nil {
diff --git a/pkg/sentry/syscalls/linux/vfs2/socket.go b/pkg/sentry/syscalls/linux/vfs2/socket.go
index 7636ca453..346fd1cea 100644
--- a/pkg/sentry/syscalls/linux/vfs2/socket.go
+++ b/pkg/sentry/syscalls/linux/vfs2/socket.go
@@ -660,6 +660,10 @@ func RecvMMsg(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
return 0, nil, syserror.EINVAL
}
+ if vlen > linux.UIO_MAXIOV {
+ vlen = linux.UIO_MAXIOV
+ }
+
// Reject flags that we don't handle yet.
if flags & ^(baseRecvFlags|linux.MSG_CMSG_CLOEXEC|linux.MSG_ERRQUEUE) != 0 {
return 0, nil, syserror.EINVAL
@@ -941,6 +945,10 @@ func SendMMsg(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.Sysc
return 0, nil, syserror.EINVAL
}
+ if vlen > linux.UIO_MAXIOV {
+ vlen = linux.UIO_MAXIOV
+ }
+
// Get socket from the file descriptor.
file := t.GetFileVFS2(fd)
if file == nil {
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD
index 31dc2525c..1a492bca3 100644
--- a/test/syscalls/linux/BUILD
+++ b/test/syscalls/linux/BUILD
@@ -2305,7 +2305,7 @@ cc_library(
name = "socket_generic_test_cases",
testonly = 1,
srcs = [
- "socket_generic.cc",
+ "socket_generic_test_cases.cc",
],
hdrs = [
"socket_generic.h",
diff --git a/test/syscalls/linux/socket_generic.cc b/test/syscalls/linux/socket_generic_test_cases.cc
index f70047a09..5c4cb6c35 100644
--- a/test/syscalls/linux/socket_generic.cc
+++ b/test/syscalls/linux/socket_generic_test_cases.cc
@@ -98,6 +98,27 @@ TEST_P(AllSocketPairTest, BasicSendmmsg) {
EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
}
+TEST_P(AllSocketPairTest, SendmmsgIsLimitedByMAXIOV) {
+ std::unique_ptr<SocketPair> sockets =
+ ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
+ char c = 0;
+
+ std::vector<struct mmsghdr> msgs(UIO_MAXIOV + 1);
+ std::vector<struct iovec> iovs(msgs.size());
+ for (size_t i = 0; i < msgs.size(); i++) {
+ iovs[i].iov_len = 1;
+ iovs[i].iov_base = &c;
+ msgs[i].msg_hdr.msg_iov = &iovs[i];
+ msgs[i].msg_hdr.msg_iovlen = 1;
+ }
+
+ int n;
+ ASSERT_THAT(n = RetryEINTR(sendmmsg)(sockets->first_fd(), msgs.data(),
+ msgs.size(), MSG_DONTWAIT),
+ SyscallSucceeds());
+ EXPECT_LE(n, UIO_MAXIOV);
+}
+
TEST_P(AllSocketPairTest, BasicRecvmmsg) {
auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
char sent_data[200];