gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/bind.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_P(AllSocketPairTest, Bind) {
    30    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    31    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
    32                     sockets->first_addr_size()),
    33                SyscallSucceeds());
    34  }
    35  
    36  TEST_P(AllSocketPairTest, BindTooLong) {
    37    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    38    // first_addr is a sockaddr_storage being used as a sockaddr_un. Use the full
    39    // length which is longer than expected for a Unix socket.
    40    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
    41                     sizeof(sockaddr_storage)),
    42                SyscallFailsWithErrno(EINVAL));
    43  }
    44  
    45  TEST_P(AllSocketPairTest, DoubleBindSocket) {
    46    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    47    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
    48                     sockets->first_addr_size()),
    49                SyscallSucceeds());
    50  
    51    EXPECT_THAT(
    52        bind(sockets->first_fd(), sockets->first_addr(),
    53             sockets->first_addr_size()),
    54        // Linux 4.09 returns EINVAL here, but some time before 4.19 it switched
    55        // to EADDRINUSE.
    56        AnyOf(SyscallFailsWithErrno(EADDRINUSE), SyscallFailsWithErrno(EINVAL)));
    57  }
    58  
    59  TEST_P(AllSocketPairTest, GetLocalAddr) {
    60    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    61    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
    62                     sockets->first_addr_size()),
    63                SyscallSucceeds());
    64    socklen_t addressLength = sockets->first_addr_size();
    65    struct sockaddr_storage address = {};
    66    ASSERT_THAT(getsockname(sockets->first_fd(), (struct sockaddr*)(&address),
    67                            &addressLength),
    68                SyscallSucceeds());
    69    EXPECT_EQ(
    70        0, memcmp(&address, sockets->first_addr(), sockets->first_addr_size()));
    71  }
    72  
    73  TEST_P(AllSocketPairTest, GetLocalAddrWithoutBind) {
    74    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    75    socklen_t addressLength = sockets->first_addr_size();
    76    struct sockaddr_storage received_address = {};
    77    ASSERT_THAT(
    78        getsockname(sockets->first_fd(), (struct sockaddr*)(&received_address),
    79                    &addressLength),
    80        SyscallSucceeds());
    81    struct sockaddr_storage want_address = {};
    82    want_address.ss_family = sockets->first_addr()->sa_family;
    83    EXPECT_EQ(0, memcmp(&received_address, &want_address, addressLength));
    84  }
    85  
    86  TEST_P(AllSocketPairTest, GetRemoteAddressWithoutConnect) {
    87    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    88  
    89    socklen_t addressLength = sockets->first_addr_size();
    90    struct sockaddr_storage address = {};
    91    ASSERT_THAT(getpeername(sockets->second_fd(), (struct sockaddr*)(&address),
    92                            &addressLength),
    93                SyscallFailsWithErrno(ENOTCONN));
    94  }
    95  
    96  TEST_P(AllSocketPairTest, DoubleBindAddress) {
    97    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    98    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
    99                     sockets->first_addr_size()),
   100                SyscallSucceeds());
   101  
   102    EXPECT_THAT(bind(sockets->second_fd(), sockets->first_addr(),
   103                     sockets->first_addr_size()),
   104                SyscallFailsWithErrno(EADDRINUSE));
   105  }
   106  
   107  TEST_P(AllSocketPairTest, Unbind) {
   108    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   109    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
   110                     sockets->first_addr_size()),
   111                SyscallSucceeds());
   112    ASSERT_THAT(close(sockets->release_first_fd()), SyscallSucceeds());
   113  
   114    // Filesystem Unix sockets do not release their address when closed.
   115    if (sockets->first_addr()->sa_data[0] != 0) {
   116      ASSERT_THAT(bind(sockets->second_fd(), sockets->first_addr(),
   117                       sockets->first_addr_size()),
   118                  SyscallFailsWithErrno(EADDRINUSE));
   119      return;
   120    }
   121  
   122    ASSERT_THAT(bind(sockets->second_fd(), sockets->first_addr(),
   123                     sockets->first_addr_size()),
   124                SyscallSucceeds());
   125    ASSERT_THAT(close(sockets->release_second_fd()), SyscallSucceeds());
   126  }
   127  
   128  INSTANTIATE_TEST_SUITE_P(
   129      AllUnixDomainSockets, AllSocketPairTest,
   130      ::testing::ValuesIn(VecCat<SocketPairKind>(
   131          ApplyVec<SocketPairKind>(
   132              FilesystemUnboundUnixDomainSocketPair,
   133              AllBitwiseCombinations(List<int>{SOCK_STREAM, SOCK_DGRAM,
   134                                               SOCK_SEQPACKET},
   135                                     List<int>{0, SOCK_NONBLOCK})),
   136          ApplyVec<SocketPairKind>(
   137              AbstractUnboundUnixDomainSocketPair,
   138              AllBitwiseCombinations(List<int>{SOCK_STREAM, SOCK_DGRAM,
   139                                               SOCK_SEQPACKET},
   140                                     List<int>{0, SOCK_NONBLOCK})))));
   141  
   142  }  // namespace
   143  
   144  }  // namespace testing
   145  }  // namespace gvisor