github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_unix_unbound_abstract.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/un.h> 17 18 #include "gtest/gtest.h" 19 #include "test/syscalls/linux/socket_test_util.h" 20 #include "test/syscalls/linux/unix_domain_socket_test_util.h" 21 #include "test/util/test_util.h" 22 23 namespace gvisor { 24 namespace testing { 25 26 namespace { 27 28 // Test fixture for tests that apply to pairs of unbound abstract unix sockets. 29 using UnboundAbstractUnixSocketPairTest = SocketPairTest; 30 31 TEST_P(UnboundAbstractUnixSocketPairTest, AddressAfterNull) { 32 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 33 34 struct sockaddr_un addr = 35 *reinterpret_cast<const struct sockaddr_un*>(sockets->first_addr()); 36 ASSERT_EQ(addr.sun_path[sizeof(addr.sun_path) - 1], 0); 37 SKIP_IF(addr.sun_path[sizeof(addr.sun_path) - 2] != 0 || 38 addr.sun_path[sizeof(addr.sun_path) - 3] != 0); 39 40 addr.sun_path[sizeof(addr.sun_path) - 2] = 'a'; 41 42 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 43 sockets->first_addr_size()), 44 SyscallSucceeds()); 45 46 ASSERT_THAT(bind(sockets->second_fd(), 47 reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), 48 SyscallSucceeds()); 49 } 50 51 TEST_P(UnboundAbstractUnixSocketPairTest, ShortAddressNotExtended) { 52 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 53 54 struct sockaddr_un addr = 55 *reinterpret_cast<const struct sockaddr_un*>(sockets->first_addr()); 56 ASSERT_EQ(addr.sun_path[sizeof(addr.sun_path) - 1], 0); 57 58 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 59 sockets->first_addr_size() - 1), 60 SyscallSucceeds()); 61 62 ASSERT_THAT(bind(sockets->second_fd(), sockets->first_addr(), 63 sockets->first_addr_size()), 64 SyscallSucceeds()); 65 } 66 67 TEST_P(UnboundAbstractUnixSocketPairTest, BindNothing) { 68 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 69 struct sockaddr_un addr = {.sun_family = AF_UNIX}; 70 ASSERT_THAT(bind(sockets->first_fd(), 71 reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), 72 SyscallSucceeds()); 73 } 74 75 TEST_P(UnboundAbstractUnixSocketPairTest, ListenZeroBacklog) { 76 SKIP_IF((GetParam().type & SOCK_DGRAM) != 0); 77 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 78 struct sockaddr_un addr = {}; 79 addr.sun_family = AF_UNIX; 80 constexpr char kPath[] = "\x00/foo_bar"; 81 memcpy(addr.sun_path, kPath, sizeof(kPath)); 82 ASSERT_THAT(bind(sockets->first_fd(), 83 reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), 84 SyscallSucceeds()); 85 ASSERT_THAT(listen(sockets->first_fd(), 0 /* backlog */), SyscallSucceeds()); 86 ASSERT_THAT(connect(sockets->second_fd(), 87 reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), 88 SyscallSucceeds()); 89 auto sockets2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 90 { 91 // Set the FD to O_NONBLOCK. 92 int opts; 93 int orig_opts; 94 ASSERT_THAT(opts = fcntl(sockets2->first_fd(), F_GETFL), SyscallSucceeds()); 95 orig_opts = opts; 96 opts |= O_NONBLOCK; 97 ASSERT_THAT(fcntl(sockets2->first_fd(), F_SETFL, opts), SyscallSucceeds()); 98 99 ASSERT_THAT( 100 connect(sockets2->first_fd(), reinterpret_cast<struct sockaddr*>(&addr), 101 sizeof(addr)), 102 SyscallFailsWithErrno(EAGAIN)); 103 } 104 { 105 // Set the FD to O_NONBLOCK. 106 int opts; 107 int orig_opts; 108 ASSERT_THAT(opts = fcntl(sockets2->second_fd(), F_GETFL), 109 SyscallSucceeds()); 110 orig_opts = opts; 111 opts |= O_NONBLOCK; 112 ASSERT_THAT(fcntl(sockets2->second_fd(), F_SETFL, opts), SyscallSucceeds()); 113 114 ASSERT_THAT( 115 connect(sockets2->second_fd(), 116 reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)), 117 SyscallFailsWithErrno(EAGAIN)); 118 } 119 } 120 121 TEST_P(UnboundAbstractUnixSocketPairTest, GetSockNameFullLength) { 122 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 123 124 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 125 sockets->first_addr_size()), 126 SyscallSucceeds()); 127 128 sockaddr_storage addr = {}; 129 socklen_t addr_len = sizeof(addr); 130 ASSERT_THAT(getsockname(sockets->first_fd(), 131 reinterpret_cast<struct sockaddr*>(&addr), &addr_len), 132 SyscallSucceeds()); 133 EXPECT_EQ(addr_len, sockets->first_addr_size()); 134 } 135 136 TEST_P(UnboundAbstractUnixSocketPairTest, GetSockNamePartialLength) { 137 auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair()); 138 139 ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(), 140 sockets->first_addr_size() - 1), 141 SyscallSucceeds()); 142 143 sockaddr_storage addr = {}; 144 socklen_t addr_len = sizeof(addr); 145 ASSERT_THAT(getsockname(sockets->first_fd(), 146 reinterpret_cast<struct sockaddr*>(&addr), &addr_len), 147 SyscallSucceeds()); 148 EXPECT_EQ(addr_len, sockets->first_addr_size() - 1); 149 } 150 151 INSTANTIATE_TEST_SUITE_P( 152 AllUnixDomainSockets, UnboundAbstractUnixSocketPairTest, 153 ::testing::ValuesIn(ApplyVec<SocketPairKind>( 154 AbstractUnboundUnixDomainSocketPair, 155 AllBitwiseCombinations(List<int>{SOCK_STREAM, SOCK_SEQPACKET, 156 SOCK_DGRAM}, 157 List<int>{0, SOCK_NONBLOCK})))); 158 159 } // namespace 160 161 } // namespace testing 162 } // namespace gvisor