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