gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/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 <errno.h>
    16  #include <fcntl.h>
    17  #include <stddef.h>
    18  #include <stdio.h>
    19  #include <sys/un.h>
    20  
    21  #include "gmock/gmock.h"
    22  #include "gtest/gtest.h"
    23  #include "test/syscalls/linux/unix_domain_socket_test_util.h"
    24  #include "test/util/cleanup.h"
    25  #include "test/util/file_descriptor.h"
    26  #include "test/util/linux_capability_util.h"
    27  #include "test/util/socket_util.h"
    28  #include "test/util/test_util.h"
    29  
    30  namespace gvisor {
    31  namespace testing {
    32  
    33  namespace {
    34  
    35  // Test fixture for tests that apply to pairs of unbound abstract unix sockets.
    36  using UnboundAbstractUnixSocketPairTest = SocketPairTest;
    37  
    38  TEST_P(UnboundAbstractUnixSocketPairTest, AddressAfterNull) {
    39    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    40  
    41    struct sockaddr_un addr =
    42        *reinterpret_cast<const struct sockaddr_un*>(sockets->first_addr());
    43    ASSERT_EQ(addr.sun_path[sizeof(addr.sun_path) - 1], 0);
    44    SKIP_IF(addr.sun_path[sizeof(addr.sun_path) - 2] != 0 ||
    45            addr.sun_path[sizeof(addr.sun_path) - 3] != 0);
    46  
    47    addr.sun_path[sizeof(addr.sun_path) - 2] = 'a';
    48  
    49    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
    50                     sockets->first_addr_size()),
    51                SyscallSucceeds());
    52  
    53    ASSERT_THAT(bind(sockets->second_fd(),
    54                     reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)),
    55                SyscallSucceeds());
    56  }
    57  
    58  TEST_P(UnboundAbstractUnixSocketPairTest, ShortAddressNotExtended) {
    59    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    60  
    61    struct sockaddr_un addr =
    62        *reinterpret_cast<const struct sockaddr_un*>(sockets->first_addr());
    63    ASSERT_EQ(addr.sun_path[sizeof(addr.sun_path) - 1], 0);
    64  
    65    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
    66                     sockets->first_addr_size() - 1),
    67                SyscallSucceeds());
    68  
    69    ASSERT_THAT(bind(sockets->second_fd(), sockets->first_addr(),
    70                     sockets->first_addr_size()),
    71                SyscallSucceeds());
    72  }
    73  
    74  TEST_P(UnboundAbstractUnixSocketPairTest, BindNothing) {
    75    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    76    struct sockaddr_un addr = {.sun_family = AF_UNIX};
    77    ASSERT_THAT(bind(sockets->first_fd(),
    78                     reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)),
    79                SyscallSucceeds());
    80  }
    81  
    82  TEST_P(UnboundAbstractUnixSocketPairTest, AutoBindSuccess) {
    83    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    84    struct sockaddr_un addr = {.sun_family = AF_UNIX};
    85    ASSERT_THAT(
    86        bind(sockets->first_fd(), reinterpret_cast<struct sockaddr*>(&addr),
    87             sizeof(sa_family_t)),
    88        SyscallSucceeds());
    89    socklen_t addr_len = sizeof(addr);
    90    ASSERT_THAT(getsockname(sockets->first_fd(),
    91                            reinterpret_cast<struct sockaddr*>(&addr), &addr_len),
    92                SyscallSucceeds());
    93    // The address consists of a null byte followed by 5 bytes in the character
    94    // set [0-9a-f].
    95    EXPECT_EQ(offsetof(struct sockaddr_un, sun_path) + 6, addr_len);
    96    EXPECT_EQ(addr.sun_path[0], 0);
    97    for (int i = 1; i < 6; i++) {
    98      char c = addr.sun_path[i];
    99      EXPECT_TRUE((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'));
   100    }
   101    if ((GetParam().type & SOCK_DGRAM) == 0) {
   102      ASSERT_THAT(listen(sockets->first_fd(), 0 /* backlog */),
   103                  SyscallSucceeds());
   104    }
   105    ASSERT_THAT(connect(sockets->second_fd(),
   106                        reinterpret_cast<struct sockaddr*>(&addr), addr_len),
   107                SyscallSucceeds());
   108  }
   109  
   110  TEST_P(UnboundAbstractUnixSocketPairTest, AutoBindAddrInUse) {
   111    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   112    struct sockaddr_un addr = {.sun_family = AF_UNIX};
   113    ASSERT_THAT(
   114        bind(sockets->first_fd(), reinterpret_cast<struct sockaddr*>(&addr),
   115             sizeof(sa_family_t)),
   116        SyscallSucceeds());
   117    socklen_t addr_len = sizeof(addr);
   118    ASSERT_THAT(getsockname(sockets->first_fd(),
   119                            reinterpret_cast<struct sockaddr*>(&addr), &addr_len),
   120                SyscallSucceeds());
   121    ASSERT_THAT(bind(sockets->second_fd(),
   122                     reinterpret_cast<struct sockaddr*>(&addr), addr_len),
   123                SyscallFailsWithErrno(EADDRINUSE));
   124  }
   125  
   126  TEST_P(UnboundAbstractUnixSocketPairTest, BindConnectInSubNamespace) {
   127    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_NET_ADMIN)));
   128  
   129    const FileDescriptor ns =
   130        ASSERT_NO_ERRNO_AND_VALUE(Open("/proc/self/ns/net", O_RDONLY));
   131    auto cleanup =
   132        Cleanup([&ns] { ASSERT_THAT(setns(ns.get(), 0), SyscallSucceeds()); });
   133    ASSERT_THAT(unshare(CLONE_NEWNET), SyscallSucceeds());
   134  
   135    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   136    ASSERT_THAT(unshare(CLONE_NEWNET), SyscallSucceeds());
   137  
   138    struct sockaddr_un addr = {.sun_family = AF_UNIX};
   139    ASSERT_THAT(
   140        bind(sockets->first_fd(), reinterpret_cast<struct sockaddr*>(&addr),
   141             sizeof(sa_family_t)),
   142        SyscallSucceeds());
   143    socklen_t addr_len = sizeof(addr);
   144    ASSERT_THAT(getsockname(sockets->first_fd(),
   145                            reinterpret_cast<struct sockaddr*>(&addr), &addr_len),
   146                SyscallSucceeds());
   147    if ((GetParam().type & SOCK_DGRAM) == 0) {
   148      ASSERT_THAT(listen(sockets->first_fd(), 1 /* backlog */),
   149                  SyscallSucceeds());
   150    }
   151    EXPECT_THAT(connect(sockets->second_fd(),
   152                        reinterpret_cast<struct sockaddr*>(&addr), addr_len),
   153                SyscallSucceeds());
   154  
   155    auto socketsInSubNS = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   156    EXPECT_THAT(connect(socketsInSubNS->second_fd(),
   157                        reinterpret_cast<struct sockaddr*>(&addr), addr_len),
   158                SyscallFailsWithErrno(ECONNREFUSED));
   159    EXPECT_THAT(bind(socketsInSubNS->first_fd(),
   160                     reinterpret_cast<struct sockaddr*>(&addr), addr_len),
   161                SyscallSucceeds());
   162  }
   163  
   164  TEST_P(UnboundAbstractUnixSocketPairTest, ListenZeroBacklog) {
   165    SKIP_IF((GetParam().type & SOCK_DGRAM) != 0);
   166    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   167    struct sockaddr_un addr = {};
   168    addr.sun_family = AF_UNIX;
   169    constexpr char kPath[] = "\x00/foo_bar";
   170    memcpy(addr.sun_path, kPath, sizeof(kPath));
   171    ASSERT_THAT(bind(sockets->first_fd(),
   172                     reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)),
   173                SyscallSucceeds());
   174    ASSERT_THAT(listen(sockets->first_fd(), 0 /* backlog */), SyscallSucceeds());
   175    ASSERT_THAT(connect(sockets->second_fd(),
   176                        reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)),
   177                SyscallSucceeds());
   178    auto sockets2 = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   179    {
   180      // Set the FD to O_NONBLOCK.
   181      int opts;
   182      ASSERT_THAT(opts = fcntl(sockets2->first_fd(), F_GETFL), SyscallSucceeds());
   183      opts |= O_NONBLOCK;
   184      ASSERT_THAT(fcntl(sockets2->first_fd(), F_SETFL, opts), SyscallSucceeds());
   185  
   186      ASSERT_THAT(
   187          connect(sockets2->first_fd(), reinterpret_cast<struct sockaddr*>(&addr),
   188                  sizeof(addr)),
   189          SyscallFailsWithErrno(EAGAIN));
   190    }
   191    {
   192      // Set the FD to O_NONBLOCK.
   193      int opts;
   194      ASSERT_THAT(opts = fcntl(sockets2->second_fd(), F_GETFL),
   195                  SyscallSucceeds());
   196      opts |= O_NONBLOCK;
   197      ASSERT_THAT(fcntl(sockets2->second_fd(), F_SETFL, opts), SyscallSucceeds());
   198  
   199      ASSERT_THAT(
   200          connect(sockets2->second_fd(),
   201                  reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)),
   202          SyscallFailsWithErrno(EAGAIN));
   203    }
   204  }
   205  
   206  TEST_P(UnboundAbstractUnixSocketPairTest, GetSockNameFullLength) {
   207    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   208  
   209    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
   210                     sockets->first_addr_size()),
   211                SyscallSucceeds());
   212  
   213    sockaddr_storage addr = {};
   214    socklen_t addr_len = sizeof(addr);
   215    ASSERT_THAT(getsockname(sockets->first_fd(),
   216                            reinterpret_cast<struct sockaddr*>(&addr), &addr_len),
   217                SyscallSucceeds());
   218    EXPECT_EQ(addr_len, sockets->first_addr_size());
   219  }
   220  
   221  TEST_P(UnboundAbstractUnixSocketPairTest, GetSockNamePartialLength) {
   222    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   223  
   224    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
   225                     sockets->first_addr_size() - 1),
   226                SyscallSucceeds());
   227  
   228    sockaddr_storage addr = {};
   229    socklen_t addr_len = sizeof(addr);
   230    ASSERT_THAT(getsockname(sockets->first_fd(),
   231                            reinterpret_cast<struct sockaddr*>(&addr), &addr_len),
   232                SyscallSucceeds());
   233    EXPECT_EQ(addr_len, sockets->first_addr_size() - 1);
   234  }
   235  
   236  INSTANTIATE_TEST_SUITE_P(
   237      AllUnixDomainSockets, UnboundAbstractUnixSocketPairTest,
   238      ::testing::ValuesIn(ApplyVec<SocketPairKind>(
   239          AbstractUnboundUnixDomainSocketPair,
   240          AllBitwiseCombinations(List<int>{SOCK_STREAM, SOCK_SEQPACKET,
   241                                           SOCK_DGRAM},
   242                                 List<int>{0, SOCK_NONBLOCK}))));
   243  
   244  }  // namespace
   245  
   246  }  // namespace testing
   247  }  // namespace gvisor