From d45420b1528b8ad23e8f12fe81fb9cc148b83012 Mon Sep 17 00:00:00 2001 From: Nayana Bidari Date: Fri, 11 Dec 2020 13:29:05 -0800 Subject: Fix panic when IPv4 address is used in sendmsg for IPv6 sockets We do not rely on error for getsockopt options(which have boolean values) anymore. This will cause issue in sendmsg where we used to return error for IPV6_V6Only option. Fix the panic by returning error (for sockets other than TCP and UDP) if the address does not match the type(AF_INET/AF_INET6) of the socket. PiperOrigin-RevId: 347063838 --- test/syscalls/linux/raw_socket.cc | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'test/syscalls') diff --git a/test/syscalls/linux/raw_socket.cc b/test/syscalls/linux/raw_socket.cc index 54709371c..c108c45df 100644 --- a/test/syscalls/linux/raw_socket.cc +++ b/test/syscalls/linux/raw_socket.cc @@ -852,6 +852,51 @@ TEST(RawSocketTest, IPv6ProtoRaw) { SyscallFailsWithErrno(EINVAL)); } +TEST(RawSocketTest, IPv6SendMsg) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + int sock; + ASSERT_THAT(sock = socket(AF_INET6, SOCK_RAW, IPPROTO_TCP), + SyscallSucceeds()); + + char kBuf[] = "hello"; + struct iovec iov = {}; + iov.iov_base = static_cast(const_cast(kBuf)); + iov.iov_len = static_cast(sizeof(kBuf)); + + struct sockaddr_storage addr = {}; + struct sockaddr_in* sin = reinterpret_cast(&addr); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + struct msghdr msg = {}; + msg.msg_name = static_cast(&addr); + msg.msg_namelen = sizeof(sockaddr_in); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + ASSERT_THAT(sendmsg(sock, &msg, 0), SyscallFailsWithErrno(EINVAL)); +} + +TEST_P(RawSocketTest, ConnectOnIPv6Socket) { + SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_RAW))); + + int sock; + ASSERT_THAT(sock = socket(AF_INET6, SOCK_RAW, IPPROTO_TCP), + SyscallSucceeds()); + + struct sockaddr_storage addr = {}; + struct sockaddr_in* sin = reinterpret_cast(&addr); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + ASSERT_THAT(connect(sock, reinterpret_cast(&addr), + sizeof(sockaddr_in6)), + SyscallFailsWithErrno(EINVAL)); +} + INSTANTIATE_TEST_SUITE_P( AllInetTests, RawSocketTest, ::testing::Combine(::testing::Values(IPPROTO_TCP, IPPROTO_UDP), -- cgit v1.2.3