gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_netlink.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 <linux/netlink.h>
    16  #include <sys/socket.h>
    17  #include <sys/types.h>
    18  #include <unistd.h>
    19  
    20  #include "gmock/gmock.h"
    21  #include "gtest/gtest.h"
    22  #include "test/util/file_descriptor.h"
    23  #include "test/util/posix_error.h"
    24  #include "test/util/socket_util.h"
    25  #include "test/util/test_util.h"
    26  
    27  // Tests for all netlink socket protocols.
    28  
    29  namespace gvisor {
    30  namespace testing {
    31  
    32  namespace {
    33  
    34  // NetlinkTest parameter is the protocol to test.
    35  using NetlinkTest = ::testing::TestWithParam<int>;
    36  
    37  // Netlink sockets must be SOCK_DGRAM or SOCK_RAW.
    38  TEST_P(NetlinkTest, Types) {
    39    const int protocol = GetParam();
    40  
    41    EXPECT_THAT(socket(AF_NETLINK, SOCK_STREAM, protocol),
    42                SyscallFailsWithErrno(ESOCKTNOSUPPORT));
    43    EXPECT_THAT(socket(AF_NETLINK, SOCK_SEQPACKET, protocol),
    44                SyscallFailsWithErrno(ESOCKTNOSUPPORT));
    45    EXPECT_THAT(socket(AF_NETLINK, SOCK_RDM, protocol),
    46                SyscallFailsWithErrno(ESOCKTNOSUPPORT));
    47    EXPECT_THAT(socket(AF_NETLINK, SOCK_DCCP, protocol),
    48                SyscallFailsWithErrno(ESOCKTNOSUPPORT));
    49    EXPECT_THAT(socket(AF_NETLINK, SOCK_PACKET, protocol),
    50                SyscallFailsWithErrno(ESOCKTNOSUPPORT));
    51  
    52    int fd;
    53    EXPECT_THAT(fd = socket(AF_NETLINK, SOCK_DGRAM, protocol), SyscallSucceeds());
    54    EXPECT_THAT(close(fd), SyscallSucceeds());
    55  
    56    EXPECT_THAT(fd = socket(AF_NETLINK, SOCK_RAW, protocol), SyscallSucceeds());
    57    EXPECT_THAT(close(fd), SyscallSucceeds());
    58  }
    59  
    60  TEST_P(NetlinkTest, AutomaticPort) {
    61    const int protocol = GetParam();
    62  
    63    FileDescriptor fd =
    64        ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_NETLINK, SOCK_RAW, protocol));
    65  
    66    struct sockaddr_nl addr = {};
    67    addr.nl_family = AF_NETLINK;
    68  
    69    EXPECT_THAT(
    70        bind(fd.get(), reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)),
    71        SyscallSucceeds());
    72  
    73    socklen_t addrlen = sizeof(addr);
    74    EXPECT_THAT(getsockname(fd.get(), reinterpret_cast<struct sockaddr*>(&addr),
    75                            &addrlen),
    76                SyscallSucceeds());
    77    EXPECT_EQ(addrlen, sizeof(addr));
    78    // This is the only netlink socket in the process, so it should get the PID as
    79    // the port id.
    80    //
    81    // N.B. Another process could theoretically have explicitly reserved our pid
    82    // as a port ID, but that is very unlikely.
    83    EXPECT_EQ(addr.nl_pid, getpid());
    84  }
    85  
    86  // Calling connect automatically binds to an automatic port.
    87  TEST_P(NetlinkTest, ConnectBinds) {
    88    const int protocol = GetParam();
    89  
    90    FileDescriptor fd =
    91        ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_NETLINK, SOCK_RAW, protocol));
    92  
    93    struct sockaddr_nl addr = {};
    94    addr.nl_family = AF_NETLINK;
    95  
    96    EXPECT_THAT(connect(fd.get(), reinterpret_cast<struct sockaddr*>(&addr),
    97                        sizeof(addr)),
    98                SyscallSucceeds());
    99  
   100    socklen_t addrlen = sizeof(addr);
   101    EXPECT_THAT(getsockname(fd.get(), reinterpret_cast<struct sockaddr*>(&addr),
   102                            &addrlen),
   103                SyscallSucceeds());
   104    EXPECT_EQ(addrlen, sizeof(addr));
   105  
   106    // Each test is running in a pid namespace, so another process can explicitly
   107    // reserve our pid as a port ID. In this case, a negative portid value will be
   108    // set.
   109    if (static_cast<pid_t>(addr.nl_pid) > 0) {
   110      EXPECT_EQ(addr.nl_pid, getpid());
   111    }
   112  
   113    memset(&addr, 0, sizeof(addr));
   114    addr.nl_family = AF_NETLINK;
   115  
   116    // Connecting again is allowed, but keeps the same port.
   117    EXPECT_THAT(connect(fd.get(), reinterpret_cast<struct sockaddr*>(&addr),
   118                        sizeof(addr)),
   119                SyscallSucceeds());
   120  
   121    addrlen = sizeof(addr);
   122    EXPECT_THAT(getsockname(fd.get(), reinterpret_cast<struct sockaddr*>(&addr),
   123                            &addrlen),
   124                SyscallSucceeds());
   125    EXPECT_EQ(addrlen, sizeof(addr));
   126    EXPECT_EQ(addr.nl_pid, getpid());
   127  }
   128  
   129  TEST_P(NetlinkTest, GetPeerName) {
   130    const int protocol = GetParam();
   131  
   132    FileDescriptor fd =
   133        ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_NETLINK, SOCK_RAW, protocol));
   134  
   135    struct sockaddr_nl addr = {};
   136    socklen_t addrlen = sizeof(addr);
   137  
   138    EXPECT_THAT(getpeername(fd.get(), reinterpret_cast<struct sockaddr*>(&addr),
   139                            &addrlen),
   140                SyscallSucceeds());
   141  
   142    EXPECT_EQ(addrlen, sizeof(addr));
   143    EXPECT_EQ(addr.nl_family, AF_NETLINK);
   144    // Peer is the kernel if we didn't connect elsewhere.
   145    EXPECT_EQ(addr.nl_pid, 0);
   146  }
   147  
   148  TEST_P(NetlinkTest, GetSendTimeout) {
   149    const int protocol = GetParam();
   150  
   151    FileDescriptor fd =
   152        ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_NETLINK, SOCK_RAW, protocol));
   153  
   154    // tv_usec should be a multiple of 4000 to work on most systems.
   155    struct timeval tv_to_set {
   156      .tv_sec = 1, .tv_usec = 40000
   157    };
   158    EXPECT_THAT(setsockopt(fd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv_to_set,
   159                           sizeof(tv_to_set)),
   160                SyscallSucceeds());
   161    struct timeval tv {
   162      .tv_sec = -1, .tv_usec = -1
   163    };
   164    socklen_t len = sizeof(tv);
   165    EXPECT_THAT(getsockopt(fd.get(), SOL_SOCKET, SO_SNDTIMEO, &tv, &len),
   166                SyscallSucceeds());
   167    EXPECT_EQ(tv.tv_sec, tv_to_set.tv_sec);
   168    EXPECT_EQ(tv.tv_usec, tv_to_set.tv_usec);
   169  }
   170  
   171  TEST_P(NetlinkTest, GetReceiveTimeout) {
   172    const int protocol = GetParam();
   173  
   174    FileDescriptor fd =
   175        ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_NETLINK, SOCK_RAW, protocol));
   176  
   177    // tv_usec should be a multiple of 4000 to work on most systems.
   178    struct timeval tv_to_set {
   179      .tv_sec = 1, .tv_usec = 8000
   180    };
   181    EXPECT_THAT(setsockopt(fd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv_to_set,
   182                           sizeof(tv_to_set)),
   183                SyscallSucceeds());
   184    struct timeval tv {
   185      .tv_sec = -1, .tv_usec = -1
   186    };
   187    socklen_t len = sizeof(tv);
   188    EXPECT_THAT(getsockopt(fd.get(), SOL_SOCKET, SO_RCVTIMEO, &tv, &len),
   189                SyscallSucceeds());
   190    EXPECT_EQ(tv.tv_sec, tv_to_set.tv_sec);
   191    EXPECT_EQ(tv.tv_usec, tv_to_set.tv_usec);
   192  }
   193  
   194  INSTANTIATE_TEST_SUITE_P(ProtocolTest, NetlinkTest,
   195                           ::testing::Values(NETLINK_ROUTE,
   196                                             NETLINK_KOBJECT_UEVENT));
   197  
   198  }  // namespace
   199  
   200  }  // namespace testing
   201  }  // namespace gvisor