github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_unix.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 "test/syscalls/linux/socket_unix.h" 16 17 #include <errno.h> 18 #include <net/if.h> 19 #include <stdio.h> 20 #include <sys/ioctl.h> 21 #include <sys/socket.h> 22 #include <sys/types.h> 23 #include <sys/un.h> 24 25 #include <vector> 26 27 #include "gtest/gtest.h" 28 #include "absl/strings/string_view.h" 29 #include "test/syscalls/linux/socket_test_util.h" 30 #include "test/syscalls/linux/unix_domain_socket_test_util.h" 31 #include "test/util/test_util.h" 32 #include "test/util/thread_util.h" 33 34 // This file contains tests specific to Unix domain sockets. It does not contain 35 // tests for UDS control messages. Those belong in socket_unix_cmsg.cc. 36 // 37 // This file is a generic socket test file. It must be built with another file 38 // that provides the test types. 39 40 namespace gvisor { 41 namespace testing { 42 43 namespace { 44 45 TEST_P(UnixSocketPairTest, InvalidGetSockOpt) { 46 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 47 int opt; 48 socklen_t optlen = sizeof(opt); 49 EXPECT_THAT(getsockopt(sockets->first_fd(), SOL_SOCKET, -1, &opt, &optlen), 50 SyscallFailsWithErrno(ENOPROTOOPT)); 51 } 52 53 TEST_P(UnixSocketPairTest, BindToBadName) { 54 auto pair = 55 ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create()); 56 57 constexpr char kBadName[] = "/some/path/that/does/not/exist"; 58 sockaddr_un sockaddr; 59 sockaddr.sun_family = AF_LOCAL; 60 memcpy(sockaddr.sun_path, kBadName, sizeof(kBadName)); 61 62 EXPECT_THAT( 63 bind(pair->first_fd(), reinterpret_cast<struct sockaddr*>(&sockaddr), 64 sizeof(sockaddr)), 65 SyscallFailsWithErrno(ENOENT)); 66 } 67 68 TEST_P(UnixSocketPairTest, BindToBadFamily) { 69 auto pair = 70 ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create()); 71 72 constexpr char kBadName[] = "/some/path/that/does/not/exist"; 73 sockaddr_un sockaddr; 74 sockaddr.sun_family = AF_INET; 75 memcpy(sockaddr.sun_path, kBadName, sizeof(kBadName)); 76 77 EXPECT_THAT( 78 bind(pair->first_fd(), reinterpret_cast<struct sockaddr*>(&sockaddr), 79 sizeof(sockaddr)), 80 SyscallFailsWithErrno(EINVAL)); 81 } 82 83 TEST_P(UnixSocketPairTest, RecvmmsgTimeoutAfterRecv) { 84 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 85 char sent_data[10]; 86 RandomizeBuffer(sent_data, sizeof(sent_data)); 87 88 char received_data[sizeof(sent_data) * 2]; 89 std::vector<struct mmsghdr> msgs(2); 90 std::vector<struct iovec> iovs(msgs.size()); 91 const int chunk_size = sizeof(received_data) / msgs.size(); 92 for (size_t i = 0; i < msgs.size(); i++) { 93 iovs[i].iov_len = chunk_size; 94 iovs[i].iov_base = &received_data[i * chunk_size]; 95 msgs[i].msg_hdr.msg_iov = &iovs[i]; 96 msgs[i].msg_hdr.msg_iovlen = 1; 97 } 98 99 ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)), 100 SyscallSucceedsWithValue(sizeof(sent_data))); 101 102 struct timespec timeout = {0, 1}; 103 ASSERT_THAT(RetryEINTR(recvmmsg)(sockets->second_fd(), &msgs[0], msgs.size(), 104 0, &timeout), 105 SyscallSucceedsWithValue(1)); 106 107 EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data))); 108 109 EXPECT_EQ(chunk_size, msgs[0].msg_len); 110 } 111 112 TEST_P(UnixSocketPairTest, TIOCINQSucceeds) { 113 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 114 115 if (IsRunningOnGvisor()) { 116 // TODO(gvisor.dev/issue/273): Inherited host UDS don't support TIOCINQ. 117 // Skip the test. 118 int size = -1; 119 int ret = ioctl(sockets->first_fd(), TIOCINQ, &size); 120 SKIP_IF(ret == -1 && errno == ENOTTY); 121 } 122 123 int size = -1; 124 EXPECT_THAT(ioctl(sockets->first_fd(), TIOCINQ, &size), SyscallSucceeds()); 125 EXPECT_EQ(size, 0); 126 127 const char some_data[] = "dangerzone"; 128 ASSERT_THAT( 129 RetryEINTR(send)(sockets->second_fd(), &some_data, sizeof(some_data), 0), 130 SyscallSucceeds()); 131 EXPECT_THAT(ioctl(sockets->first_fd(), TIOCINQ, &size), SyscallSucceeds()); 132 EXPECT_EQ(size, sizeof(some_data)); 133 134 // Linux only reports the first message's size, which is wrong. We test for 135 // the behavior described in the man page. 136 SKIP_IF(!IsRunningOnGvisor()); 137 138 ASSERT_THAT( 139 RetryEINTR(send)(sockets->second_fd(), &some_data, sizeof(some_data), 0), 140 SyscallSucceeds()); 141 EXPECT_THAT(ioctl(sockets->first_fd(), TIOCINQ, &size), SyscallSucceeds()); 142 EXPECT_EQ(size, sizeof(some_data) * 2); 143 } 144 145 TEST_P(UnixSocketPairTest, TIOCOUTQSucceeds) { 146 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 147 148 if (IsRunningOnGvisor()) { 149 // TODO(gvisor.dev/issue/273): Inherited host UDS don't support TIOCOUTQ. 150 // Skip the test. 151 int size = -1; 152 int ret = ioctl(sockets->second_fd(), TIOCOUTQ, &size); 153 SKIP_IF(ret == -1 && errno == ENOTTY); 154 } 155 156 int size = -1; 157 EXPECT_THAT(ioctl(sockets->second_fd(), TIOCOUTQ, &size), SyscallSucceeds()); 158 EXPECT_EQ(size, 0); 159 160 // Linux reports bogus numbers which are related to its internal allocations. 161 // We test for the behavior described in the man page. 162 SKIP_IF(!IsRunningOnGvisor()); 163 164 const char some_data[] = "dangerzone"; 165 ASSERT_THAT( 166 RetryEINTR(send)(sockets->second_fd(), &some_data, sizeof(some_data), 0), 167 SyscallSucceeds()); 168 EXPECT_THAT(ioctl(sockets->second_fd(), TIOCOUTQ, &size), SyscallSucceeds()); 169 EXPECT_EQ(size, sizeof(some_data)); 170 171 ASSERT_THAT( 172 RetryEINTR(send)(sockets->second_fd(), &some_data, sizeof(some_data), 0), 173 SyscallSucceeds()); 174 EXPECT_THAT(ioctl(sockets->second_fd(), TIOCOUTQ, &size), SyscallSucceeds()); 175 EXPECT_EQ(size, sizeof(some_data) * 2); 176 } 177 178 TEST_P(UnixSocketPairTest, NetdeviceIoctlsSucceed) { 179 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 180 181 // Prepare the request. 182 struct ifreq ifr; 183 snprintf(ifr.ifr_name, IFNAMSIZ, "lo"); 184 185 // Check that the ioctl either succeeds or fails with ENODEV. 186 int err = ioctl(sockets->first_fd(), SIOCGIFINDEX, &ifr); 187 if (err < 0) { 188 ASSERT_EQ(errno, ENODEV); 189 } 190 } 191 192 TEST_P(UnixSocketPairTest, Shutdown) { 193 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 194 195 const std::string data = "abc"; 196 ASSERT_THAT(WriteFd(sockets->first_fd(), data.c_str(), data.size()), 197 SyscallSucceedsWithValue(data.size())); 198 199 ASSERT_THAT(shutdown(sockets->first_fd(), SHUT_RDWR), SyscallSucceeds()); 200 ASSERT_THAT(shutdown(sockets->second_fd(), SHUT_RDWR), SyscallSucceeds()); 201 202 // Shutting down a socket does not clear the buffer. 203 char buf[3]; 204 ASSERT_THAT(ReadFd(sockets->second_fd(), buf, data.size()), 205 SyscallSucceedsWithValue(data.size())); 206 EXPECT_EQ(data, absl::string_view(buf, data.size())); 207 } 208 209 TEST_P(UnixSocketPairTest, ShutdownRead) { 210 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 211 212 ASSERT_THAT(shutdown(sockets->first_fd(), SHUT_RD), SyscallSucceeds()); 213 214 // When the socket is shutdown for read, read behavior varies between 215 // different socket types. This is covered by the various ReadOneSideClosed 216 // test cases. 217 218 // ... and the peer cannot write. 219 const std::string data = "abc"; 220 EXPECT_THAT(WriteFd(sockets->second_fd(), data.c_str(), data.size()), 221 SyscallFailsWithErrno(EPIPE)); 222 223 // ... but the socket can still write. 224 ASSERT_THAT(WriteFd(sockets->first_fd(), data.c_str(), data.size()), 225 SyscallSucceedsWithValue(data.size())); 226 227 // ... and the peer can still read. 228 char buf[3]; 229 EXPECT_THAT(ReadFd(sockets->second_fd(), buf, data.size()), 230 SyscallSucceedsWithValue(data.size())); 231 EXPECT_EQ(data, absl::string_view(buf, data.size())); 232 } 233 234 TEST_P(UnixSocketPairTest, ShutdownWrite) { 235 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 236 237 ASSERT_THAT(shutdown(sockets->first_fd(), SHUT_WR), SyscallSucceeds()); 238 239 // When the socket is shutdown for write, it cannot write. 240 const std::string data = "abc"; 241 EXPECT_THAT(WriteFd(sockets->first_fd(), data.c_str(), data.size()), 242 SyscallFailsWithErrno(EPIPE)); 243 244 // ... and the peer read behavior varies between different socket types. This 245 // is covered by the various ReadOneSideClosed test cases. 246 247 // ... but the peer can still write. 248 char buf[3]; 249 ASSERT_THAT(WriteFd(sockets->second_fd(), data.c_str(), data.size()), 250 SyscallSucceedsWithValue(data.size())); 251 252 // ... and the socket can still read. 253 EXPECT_THAT(ReadFd(sockets->first_fd(), buf, data.size()), 254 SyscallSucceedsWithValue(data.size())); 255 EXPECT_EQ(data, absl::string_view(buf, data.size())); 256 } 257 258 TEST_P(UnixSocketPairTest, SocketReopenFromProcfs) { 259 // TODO(gvisor.dev/issue/1624): In VFS1, we return EIO instead of ENXIO (see 260 // b/122310852). Remove this skip once VFS1 is deleted. 261 SKIP_IF(IsRunningWithVFS1()); 262 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 263 264 // Opening a socket pair via /proc/self/fd/X is a ENXIO. 265 for (const int fd : {sockets->first_fd(), sockets->second_fd()}) { 266 ASSERT_THAT(Open(absl::StrCat("/proc/self/fd/", fd), O_WRONLY), 267 PosixErrorIs(ENXIO, ::testing::_)); 268 } 269 } 270 271 } // namespace 272 273 } // namespace testing 274 } // namespace gvisor