gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_unix_unbound_dgram.cc (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <stdio.h> 16 #include <sys/socket.h> 17 #include <sys/un.h> 18 19 #include "gtest/gtest.h" 20 #include "test/syscalls/linux/unix_domain_socket_test_util.h" 21 #include "test/util/socket_util.h" 22 #include "test/util/test_util.h" 23 24 namespace gvisor { 25 namespace testing { 26 27 namespace { 28 29 // Test fixture for tests that apply to pairs of unbound dgram unix sockets. 30 using UnboundDgramUnixSocketPairTest = SocketPairTest; 31 32 TEST_P(UnboundDgramUnixSocketPairTest, BindConnect) { 33 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 34 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 35 sockets->first_addr_size()), 36 SyscallSucceeds()); 37 ASSERT_THAT(connect(sockets->second_fd(), sockets->first_addr(), 38 sockets->first_addr_size()), 39 SyscallSucceeds()); 40 } 41 42 TEST_P(UnboundDgramUnixSocketPairTest, SelfConnect) { 43 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 44 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 45 sockets->first_addr_size()), 46 SyscallSucceeds()); 47 ASSERT_THAT(connect(sockets->first_fd(), sockets->first_addr(), 48 sockets->first_addr_size()), 49 SyscallSucceeds()); 50 } 51 52 TEST_P(UnboundDgramUnixSocketPairTest, DoubleConnect) { 53 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 54 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 55 sockets->first_addr_size()), 56 SyscallSucceeds()); 57 ASSERT_THAT(connect(sockets->second_fd(), sockets->first_addr(), 58 sockets->first_addr_size()), 59 SyscallSucceeds()); 60 ASSERT_THAT(connect(sockets->second_fd(), sockets->first_addr(), 61 sockets->first_addr_size()), 62 SyscallSucceeds()); 63 } 64 65 TEST_P(UnboundDgramUnixSocketPairTest, GetRemoteAddress) { 66 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 67 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 68 sockets->first_addr_size()), 69 SyscallSucceeds()); 70 ASSERT_THAT(connect(sockets->second_fd(), sockets->first_addr(), 71 sockets->first_addr_size()), 72 SyscallSucceeds()); 73 74 socklen_t addressLength = sockets->first_addr_size(); 75 struct sockaddr_storage address = {}; 76 ASSERT_THAT(getpeername(sockets->second_fd(), (struct sockaddr*)(&address), 77 &addressLength), 78 SyscallSucceeds()); 79 EXPECT_EQ( 80 0, memcmp(&address, sockets->first_addr(), sockets->first_addr_size())); 81 } 82 83 TEST_P(UnboundDgramUnixSocketPairTest, Sendto) { 84 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 85 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 86 sockets->first_addr_size()), 87 SyscallSucceeds()); 88 89 char sent_data[20]; 90 RandomizeBuffer(sent_data, sizeof(sent_data)); 91 92 ASSERT_THAT(sendto(sockets->second_fd(), sent_data, sizeof(sent_data), 0, 93 sockets->first_addr(), sockets->first_addr_size()), 94 SyscallSucceedsWithValue(sizeof(sent_data))); 95 96 char received_data[sizeof(sent_data)]; 97 ASSERT_THAT(ReadFd(sockets->first_fd(), received_data, sizeof(received_data)), 98 SyscallSucceedsWithValue(sizeof(received_data))); 99 EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(received_data))); 100 } 101 102 TEST_P(UnboundDgramUnixSocketPairTest, ZeroWriteAllowed) { 103 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 104 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 105 sockets->first_addr_size()), 106 SyscallSucceeds()); 107 ASSERT_THAT(connect(sockets->second_fd(), sockets->first_addr(), 108 sockets->first_addr_size()), 109 SyscallSucceeds()); 110 111 char sent_data[3]; 112 // Send a zero length packet. 113 ASSERT_THAT(write(sockets->second_fd(), sent_data, 0), 114 SyscallSucceedsWithValue(0)); 115 // Receive the packet. 116 char received_data[sizeof(sent_data)]; 117 ASSERT_THAT(read(sockets->first_fd(), received_data, sizeof(received_data)), 118 SyscallSucceedsWithValue(0)); 119 } 120 121 TEST_P(UnboundDgramUnixSocketPairTest, Listen) { 122 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 123 ASSERT_THAT(listen(sockets->first_fd(), 0), SyscallFailsWithErrno(ENOTSUP)); 124 } 125 126 TEST_P(UnboundDgramUnixSocketPairTest, Accept) { 127 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 128 ASSERT_THAT(accept(sockets->first_fd(), nullptr, nullptr), 129 SyscallFailsWithErrno(ENOTSUP)); 130 } 131 132 TEST_P(UnboundDgramUnixSocketPairTest, SendtoWithoutConnect) { 133 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 134 135 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 136 sockets->first_addr_size()), 137 SyscallSucceeds()); 138 139 char data = 'a'; 140 ASSERT_THAT( 141 RetryEINTR(sendto)(sockets->second_fd(), &data, sizeof(data), 0, 142 sockets->first_addr(), sockets->first_addr_size()), 143 SyscallSucceedsWithValue(sizeof(data))); 144 } 145 146 TEST_P(UnboundDgramUnixSocketPairTest, SendtoWithoutConnectPassCreds) { 147 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 148 149 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 150 sockets->first_addr_size()), 151 SyscallSucceeds()); 152 153 SetSoPassCred(sockets->first_fd()); 154 char data = 'a'; 155 ASSERT_THAT( 156 RetryEINTR(sendto)(sockets->second_fd(), &data, sizeof(data), 0, 157 sockets->first_addr(), sockets->first_addr_size()), 158 SyscallSucceedsWithValue(sizeof(data))); 159 ucred creds; 160 creds.pid = -1; 161 char buf[sizeof(data) + 1]; 162 ASSERT_NO_FATAL_FAILURE( 163 RecvCreds(sockets->first_fd(), &creds, buf, sizeof(buf), sizeof(data))); 164 EXPECT_EQ(0, memcmp(&data, buf, sizeof(data))); 165 EXPECT_THAT(getpid(), SyscallSucceedsWithValue(creds.pid)); 166 } 167 168 INSTANTIATE_TEST_SUITE_P( 169 AllUnixDomainSockets, UnboundDgramUnixSocketPairTest, 170 ::testing::ValuesIn(VecCat<SocketPairKind>( 171 ApplyVec<SocketPairKind>(FilesystemUnboundUnixDomainSocketPair, 172 AllBitwiseCombinations(List<int>{SOCK_DGRAM}, 173 List<int>{ 174 0, SOCK_NONBLOCK})), 175 ApplyVec<SocketPairKind>( 176 AbstractUnboundUnixDomainSocketPair, 177 AllBitwiseCombinations(List<int>{SOCK_DGRAM}, 178 List<int>{0, SOCK_NONBLOCK}))))); 179 180 } // namespace 181 182 } // namespace testing 183 } // namespace gvisor