gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/socket_unix_cmsg.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 "test/syscalls/linux/socket_unix_cmsg.h"
    16  
    17  #include <errno.h>
    18  #include <net/if.h>
    19  #include <stdio.h>
    20  #include <sys/ioctl.h>
    21  #include <sys/socket.h>
    22  #include <sys/types.h>
    23  #include <sys/un.h>
    24  
    25  #include <vector>
    26  
    27  #include "gtest/gtest.h"
    28  #include "absl/strings/string_view.h"
    29  #include "test/syscalls/linux/unix_domain_socket_test_util.h"
    30  #include "test/util/socket_util.h"
    31  #include "test/util/test_util.h"
    32  #include "test/util/thread_util.h"
    33  
    34  // This file contains tests for control message in Unix domain sockets.
    35  //
    36  // This file is a generic socket test file. It must be built with another file
    37  // that provides the test types.
    38  
    39  namespace gvisor {
    40  namespace testing {
    41  
    42  namespace {
    43  
    44  TEST_P(UnixSocketPairCmsgTest, BasicFDPass) {
    45    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    46  
    47    char sent_data[20];
    48    RandomizeBuffer(sent_data, sizeof(sent_data));
    49  
    50    auto pair =
    51        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
    52  
    53    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
    54                                         sent_data, sizeof(sent_data)));
    55  
    56    char received_data[20];
    57    int fd = -1;
    58    ASSERT_NO_FATAL_FAILURE(RecvSingleFD(sockets->second_fd(), &fd, received_data,
    59                                         sizeof(received_data)));
    60  
    61    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
    62  
    63    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
    64  }
    65  
    66  TEST_P(UnixSocketPairCmsgTest, BasicTwoFDPass) {
    67    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    68  
    69    char sent_data[20];
    70    RandomizeBuffer(sent_data, sizeof(sent_data));
    71  
    72    auto pair1 =
    73        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
    74    auto pair2 =
    75        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
    76    int sent_fds[] = {pair1->second_fd(), pair2->second_fd()};
    77  
    78    ASSERT_NO_FATAL_FAILURE(
    79        SendFDs(sockets->first_fd(), sent_fds, 2, sent_data, sizeof(sent_data)));
    80  
    81    char received_data[20];
    82    int received_fds[] = {-1, -1};
    83  
    84    ASSERT_NO_FATAL_FAILURE(RecvFDs(sockets->second_fd(), received_fds, 2,
    85                                    received_data, sizeof(received_data)));
    86  
    87    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
    88  
    89    ASSERT_NO_FATAL_FAILURE(TransferTest(received_fds[0], pair1->first_fd()));
    90    ASSERT_NO_FATAL_FAILURE(TransferTest(received_fds[1], pair2->first_fd()));
    91  }
    92  
    93  TEST_P(UnixSocketPairCmsgTest, BasicThreeFDPass) {
    94    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    95  
    96    char sent_data[20];
    97    RandomizeBuffer(sent_data, sizeof(sent_data));
    98  
    99    auto pair1 =
   100        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   101    auto pair2 =
   102        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   103    auto pair3 =
   104        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   105    int sent_fds[] = {pair1->second_fd(), pair2->second_fd(), pair3->second_fd()};
   106  
   107    ASSERT_NO_FATAL_FAILURE(
   108        SendFDs(sockets->first_fd(), sent_fds, 3, sent_data, sizeof(sent_data)));
   109  
   110    char received_data[20];
   111    int received_fds[] = {-1, -1, -1};
   112  
   113    ASSERT_NO_FATAL_FAILURE(RecvFDs(sockets->second_fd(), received_fds, 3,
   114                                    received_data, sizeof(received_data)));
   115  
   116    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   117  
   118    ASSERT_NO_FATAL_FAILURE(TransferTest(received_fds[0], pair1->first_fd()));
   119    ASSERT_NO_FATAL_FAILURE(TransferTest(received_fds[1], pair2->first_fd()));
   120    ASSERT_NO_FATAL_FAILURE(TransferTest(received_fds[2], pair3->first_fd()));
   121  }
   122  
   123  TEST_P(UnixSocketPairCmsgTest, BadFDPass) {
   124    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   125  
   126    char sent_data[20];
   127    RandomizeBuffer(sent_data, sizeof(sent_data));
   128  
   129    int sent_fd = -1;
   130  
   131    struct msghdr msg = {};
   132    char control[CMSG_SPACE(sizeof(sent_fd))];
   133    msg.msg_control = control;
   134    msg.msg_controllen = sizeof(control);
   135  
   136    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   137    cmsg->cmsg_len = CMSG_LEN(sizeof(sent_fd));
   138    cmsg->cmsg_level = SOL_SOCKET;
   139    cmsg->cmsg_type = SCM_RIGHTS;
   140    memcpy(CMSG_DATA(cmsg), &sent_fd, sizeof(sent_fd));
   141  
   142    struct iovec iov;
   143    iov.iov_base = sent_data;
   144    iov.iov_len = sizeof(sent_data);
   145    msg.msg_iov = &iov;
   146    msg.msg_iovlen = 1;
   147  
   148    ASSERT_THAT(RetryEINTR(sendmsg)(sockets->first_fd(), &msg, 0),
   149                SyscallFailsWithErrno(EBADF));
   150  }
   151  
   152  TEST_P(UnixSocketPairCmsgTest, ShortCmsg) {
   153    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   154  
   155    char sent_data[20];
   156    RandomizeBuffer(sent_data, sizeof(sent_data));
   157  
   158    int sent_fd = -1;
   159  
   160    struct msghdr msg = {};
   161    char control[CMSG_SPACE(sizeof(sent_fd))];
   162    msg.msg_control = control;
   163    msg.msg_controllen = sizeof(control);
   164  
   165    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   166    cmsg->cmsg_len = 1;
   167    cmsg->cmsg_level = SOL_SOCKET;
   168    cmsg->cmsg_type = SCM_RIGHTS;
   169    memcpy(CMSG_DATA(cmsg), &sent_fd, sizeof(sent_fd));
   170  
   171    struct iovec iov;
   172    iov.iov_base = sent_data;
   173    iov.iov_len = sizeof(sent_data);
   174    msg.msg_iov = &iov;
   175    msg.msg_iovlen = 1;
   176  
   177    ASSERT_THAT(RetryEINTR(sendmsg)(sockets->first_fd(), &msg, 0),
   178                SyscallFailsWithErrno(EINVAL));
   179  }
   180  
   181  // BasicFDPassNoSpace starts off by sending a single FD just like BasicFDPass.
   182  // The difference is that when calling recvmsg, no space for FDs is provided,
   183  // only space for the cmsg header.
   184  TEST_P(UnixSocketPairCmsgTest, BasicFDPassNoSpace) {
   185    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   186  
   187    char sent_data[20];
   188    RandomizeBuffer(sent_data, sizeof(sent_data));
   189  
   190    auto pair =
   191        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   192  
   193    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   194                                         sent_data, sizeof(sent_data)));
   195  
   196    char received_data[20];
   197  
   198    struct msghdr msg = {};
   199    std::vector<char> control(CMSG_SPACE(0));
   200    msg.msg_control = &control[0];
   201    msg.msg_controllen = control.size();
   202  
   203    struct iovec iov;
   204    iov.iov_base = received_data;
   205    iov.iov_len = sizeof(received_data);
   206    msg.msg_iov = &iov;
   207    msg.msg_iovlen = 1;
   208  
   209    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   210                SyscallSucceedsWithValue(sizeof(received_data)));
   211  
   212    EXPECT_EQ(msg.msg_controllen, 0);
   213    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   214  }
   215  
   216  // BasicFDPassNoSpaceMsgCtrunc sends an FD, but does not provide any space to
   217  // receive it. It then verifies that the MSG_CTRUNC flag is set in the msghdr.
   218  TEST_P(UnixSocketPairCmsgTest, BasicFDPassNoSpaceMsgCtrunc) {
   219    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   220  
   221    char sent_data[20];
   222    RandomizeBuffer(sent_data, sizeof(sent_data));
   223  
   224    auto pair =
   225        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   226  
   227    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   228                                         sent_data, sizeof(sent_data)));
   229  
   230    struct msghdr msg = {};
   231    std::vector<char> control(CMSG_SPACE(0));
   232    msg.msg_control = &control[0];
   233    msg.msg_controllen = control.size();
   234  
   235    char received_data[sizeof(sent_data)];
   236    struct iovec iov;
   237    iov.iov_base = received_data;
   238    iov.iov_len = sizeof(received_data);
   239    msg.msg_iov = &iov;
   240    msg.msg_iovlen = 1;
   241  
   242    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   243                SyscallSucceedsWithValue(sizeof(received_data)));
   244  
   245    EXPECT_EQ(msg.msg_controllen, 0);
   246    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
   247  }
   248  
   249  // BasicFDPassNullControlMsgCtrunc sends an FD and sets contradictory values for
   250  // msg_controllen and msg_control. msg_controllen is set to the correct size to
   251  // accommodate the FD, but msg_control is set to NULL. In this case, msg_control
   252  // should override msg_controllen.
   253  TEST_P(UnixSocketPairCmsgTest, BasicFDPassNullControlMsgCtrunc) {
   254    // FIXME(gvisor.dev/issue/207): Fix handling of NULL msg_control.
   255    SKIP_IF(IsRunningOnGvisor());
   256  
   257    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   258  
   259    char sent_data[20];
   260    RandomizeBuffer(sent_data, sizeof(sent_data));
   261  
   262    auto pair =
   263        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   264  
   265    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   266                                         sent_data, sizeof(sent_data)));
   267  
   268    struct msghdr msg = {};
   269    msg.msg_controllen = CMSG_SPACE(1);
   270  
   271    char received_data[sizeof(sent_data)];
   272    struct iovec iov;
   273    iov.iov_base = received_data;
   274    iov.iov_len = sizeof(received_data);
   275    msg.msg_iov = &iov;
   276    msg.msg_iovlen = 1;
   277  
   278    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   279                SyscallSucceedsWithValue(sizeof(received_data)));
   280  
   281    EXPECT_EQ(msg.msg_controllen, 0);
   282    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
   283  }
   284  
   285  // BasicFDPassNotEnoughSpaceMsgCtrunc sends an FD, but does not provide enough
   286  // space to receive it. It then verifies that the MSG_CTRUNC flag is set in the
   287  // msghdr.
   288  TEST_P(UnixSocketPairCmsgTest, BasicFDPassNotEnoughSpaceMsgCtrunc) {
   289    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   290  
   291    char sent_data[20];
   292    RandomizeBuffer(sent_data, sizeof(sent_data));
   293  
   294    auto pair =
   295        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   296  
   297    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   298                                         sent_data, sizeof(sent_data)));
   299  
   300    struct msghdr msg = {};
   301    std::vector<char> control(CMSG_SPACE(0) + 1);
   302    msg.msg_control = &control[0];
   303    msg.msg_controllen = control.size();
   304  
   305    char received_data[sizeof(sent_data)];
   306    struct iovec iov;
   307    iov.iov_base = received_data;
   308    iov.iov_len = sizeof(received_data);
   309    msg.msg_iov = &iov;
   310    msg.msg_iovlen = 1;
   311  
   312    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   313                SyscallSucceedsWithValue(sizeof(received_data)));
   314  
   315    EXPECT_EQ(msg.msg_controllen, 0);
   316    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
   317  }
   318  
   319  // BasicThreeFDPassTruncationMsgCtrunc sends three FDs, but only provides enough
   320  // space to receive two of them. It then verifies that the MSG_CTRUNC flag is
   321  // set in the msghdr.
   322  TEST_P(UnixSocketPairCmsgTest, BasicThreeFDPassTruncationMsgCtrunc) {
   323    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   324  
   325    char sent_data[20];
   326    RandomizeBuffer(sent_data, sizeof(sent_data));
   327  
   328    auto pair1 =
   329        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   330    auto pair2 =
   331        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   332    auto pair3 =
   333        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   334    int sent_fds[] = {pair1->second_fd(), pair2->second_fd(), pair3->second_fd()};
   335  
   336    ASSERT_NO_FATAL_FAILURE(
   337        SendFDs(sockets->first_fd(), sent_fds, 3, sent_data, sizeof(sent_data)));
   338  
   339    struct msghdr msg = {};
   340    std::vector<char> control(CMSG_SPACE(2 * sizeof(int)));
   341    msg.msg_control = &control[0];
   342    msg.msg_controllen = control.size();
   343  
   344    char received_data[sizeof(sent_data)];
   345    struct iovec iov;
   346    iov.iov_base = received_data;
   347    iov.iov_len = sizeof(received_data);
   348    msg.msg_iov = &iov;
   349    msg.msg_iovlen = 1;
   350  
   351    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   352                SyscallSucceedsWithValue(sizeof(received_data)));
   353  
   354    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
   355  
   356    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   357    ASSERT_NE(cmsg, nullptr);
   358    EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(2 * sizeof(int)));
   359    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
   360    EXPECT_EQ(cmsg->cmsg_type, SCM_RIGHTS);
   361  }
   362  
   363  // BasicFDPassUnalignedRecv starts off by sending a single FD just like
   364  // BasicFDPass. The difference is that when calling recvmsg, the length of the
   365  // receive data is only aligned on a 4 byte boundary instead of the normal 8.
   366  TEST_P(UnixSocketPairCmsgTest, BasicFDPassUnalignedRecv) {
   367    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   368  
   369    char sent_data[20];
   370    RandomizeBuffer(sent_data, sizeof(sent_data));
   371  
   372    auto pair =
   373        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   374  
   375    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   376                                         sent_data, sizeof(sent_data)));
   377  
   378    char received_data[20];
   379    int fd = -1;
   380    ASSERT_NO_FATAL_FAILURE(RecvSingleFDUnaligned(
   381        sockets->second_fd(), &fd, received_data, sizeof(received_data)));
   382  
   383    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   384  
   385    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
   386  }
   387  
   388  // BasicFDPassUnalignedRecvNoMsgTrunc sends one FD and only provides enough
   389  // space to receive just it. (Normally the minimum amount of space one would
   390  // provide would be enough space for two FDs.) It then verifies that the
   391  // MSG_CTRUNC flag is not set in the msghdr.
   392  TEST_P(UnixSocketPairCmsgTest, BasicFDPassUnalignedRecvNoMsgTrunc) {
   393    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   394  
   395    char sent_data[20];
   396    RandomizeBuffer(sent_data, sizeof(sent_data));
   397  
   398    auto pair =
   399        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   400  
   401    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   402                                         sent_data, sizeof(sent_data)));
   403  
   404    struct msghdr msg = {};
   405    char control[CMSG_SPACE(sizeof(int)) - sizeof(int)];
   406    msg.msg_control = control;
   407    msg.msg_controllen = sizeof(control);
   408  
   409    char received_data[sizeof(sent_data)] = {};
   410    struct iovec iov;
   411    iov.iov_base = received_data;
   412    iov.iov_len = sizeof(received_data);
   413    msg.msg_iov = &iov;
   414    msg.msg_iovlen = 1;
   415  
   416    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   417                SyscallSucceedsWithValue(sizeof(received_data)));
   418  
   419    EXPECT_EQ(msg.msg_flags, 0);
   420  
   421    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   422    ASSERT_NE(cmsg, nullptr);
   423    EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
   424    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
   425    EXPECT_EQ(cmsg->cmsg_type, SCM_RIGHTS);
   426  }
   427  
   428  // BasicTwoFDPassUnalignedRecvTruncationMsgTrunc sends two FDs, but only
   429  // provides enough space to receive one of them. It then verifies that the
   430  // MSG_CTRUNC flag is set in the msghdr.
   431  TEST_P(UnixSocketPairCmsgTest, BasicTwoFDPassUnalignedRecvTruncationMsgTrunc) {
   432    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   433  
   434    char sent_data[20];
   435    RandomizeBuffer(sent_data, sizeof(sent_data));
   436  
   437    auto pair =
   438        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   439    int sent_fds[] = {pair->first_fd(), pair->second_fd()};
   440  
   441    ASSERT_NO_FATAL_FAILURE(
   442        SendFDs(sockets->first_fd(), sent_fds, 2, sent_data, sizeof(sent_data)));
   443  
   444    struct msghdr msg = {};
   445    // CMSG_SPACE rounds up to two FDs, we only want one.
   446    char control[CMSG_SPACE(sizeof(int)) - sizeof(int)];
   447    msg.msg_control = control;
   448    msg.msg_controllen = sizeof(control);
   449  
   450    char received_data[sizeof(sent_data)] = {};
   451    struct iovec iov;
   452    iov.iov_base = received_data;
   453    iov.iov_len = sizeof(received_data);
   454    msg.msg_iov = &iov;
   455    msg.msg_iovlen = 1;
   456  
   457    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   458                SyscallSucceedsWithValue(sizeof(received_data)));
   459  
   460    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
   461  
   462    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   463    ASSERT_NE(cmsg, nullptr);
   464    EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
   465    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
   466    EXPECT_EQ(cmsg->cmsg_type, SCM_RIGHTS);
   467  }
   468  
   469  TEST_P(UnixSocketPairCmsgTest, ConcurrentBasicFDPass) {
   470    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   471  
   472    char sent_data[20];
   473    RandomizeBuffer(sent_data, sizeof(sent_data));
   474  
   475    int sockfd1 = sockets->first_fd();
   476    auto recv_func = [sockfd1, sent_data]() {
   477      char received_data[20];
   478      int fd = -1;
   479      RecvSingleFD(sockfd1, &fd, received_data, sizeof(received_data));
   480      ASSERT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   481      char buf[20];
   482      ASSERT_THAT(ReadFd(fd, buf, sizeof(buf)),
   483                  SyscallSucceedsWithValue(sizeof(buf)));
   484      ASSERT_THAT(WriteFd(fd, buf, sizeof(buf)),
   485                  SyscallSucceedsWithValue(sizeof(buf)));
   486    };
   487  
   488    auto pair =
   489        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   490  
   491    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->second_fd(), pair->second_fd(),
   492                                         sent_data, sizeof(sent_data)));
   493  
   494    ScopedThread t(recv_func);
   495  
   496    RandomizeBuffer(sent_data, sizeof(sent_data));
   497    ASSERT_THAT(WriteFd(pair->first_fd(), sent_data, sizeof(sent_data)),
   498                SyscallSucceedsWithValue(sizeof(sent_data)));
   499  
   500    char received_data[20];
   501    ASSERT_THAT(ReadFd(pair->first_fd(), received_data, sizeof(received_data)),
   502                SyscallSucceedsWithValue(sizeof(received_data)));
   503  
   504    t.Join();
   505  
   506    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   507  }
   508  
   509  // FDPassNoRecv checks that the control message can be safely ignored by using
   510  // read(2) instead of recvmsg(2).
   511  TEST_P(UnixSocketPairCmsgTest, FDPassNoRecv) {
   512    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   513  
   514    char sent_data[20];
   515    RandomizeBuffer(sent_data, sizeof(sent_data));
   516  
   517    auto pair =
   518        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   519  
   520    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   521                                         sent_data, sizeof(sent_data)));
   522  
   523    // Read while ignoring the passed FD.
   524    char received_data[20];
   525    ASSERT_THAT(
   526        ReadFd(sockets->second_fd(), received_data, sizeof(received_data)),
   527        SyscallSucceedsWithValue(sizeof(received_data)));
   528  
   529    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   530  
   531    // Check that the socket still works for reads and writes.
   532    ASSERT_NO_FATAL_FAILURE(
   533        TransferTest(sockets->first_fd(), sockets->second_fd()));
   534  }
   535  
   536  // FDPassInterspersed1 checks that sent control messages cannot be read before
   537  // their associated data has been read.
   538  TEST_P(UnixSocketPairCmsgTest, FDPassInterspersed1) {
   539    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   540  
   541    char written_data[20];
   542    RandomizeBuffer(written_data, sizeof(written_data));
   543  
   544    ASSERT_THAT(WriteFd(sockets->first_fd(), written_data, sizeof(written_data)),
   545                SyscallSucceedsWithValue(sizeof(written_data)));
   546  
   547    char sent_data[20];
   548    RandomizeBuffer(sent_data, sizeof(sent_data));
   549  
   550    auto pair =
   551        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   552    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   553                                         sent_data, sizeof(sent_data)));
   554  
   555    // Check that we don't get a control message, but do get the data.
   556    char received_data[20];
   557    RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data));
   558    EXPECT_EQ(0, memcmp(written_data, received_data, sizeof(written_data)));
   559  }
   560  
   561  // FDPassInterspersed2 checks that sent control messages cannot be read after
   562  // their associated data has been read while ignoring the control message by
   563  // using read(2) instead of recvmsg(2).
   564  TEST_P(UnixSocketPairCmsgTest, FDPassInterspersed2) {
   565    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   566  
   567    char sent_data[20];
   568    RandomizeBuffer(sent_data, sizeof(sent_data));
   569  
   570    auto pair =
   571        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   572  
   573    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   574                                         sent_data, sizeof(sent_data)));
   575  
   576    char written_data[20];
   577    RandomizeBuffer(written_data, sizeof(written_data));
   578    ASSERT_THAT(WriteFd(sockets->first_fd(), written_data, sizeof(written_data)),
   579                SyscallSucceedsWithValue(sizeof(written_data)));
   580  
   581    char received_data[20];
   582    ASSERT_THAT(
   583        ReadFd(sockets->second_fd(), received_data, sizeof(received_data)),
   584        SyscallSucceedsWithValue(sizeof(received_data)));
   585  
   586    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   587  
   588    ASSERT_NO_FATAL_FAILURE(
   589        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   590    EXPECT_EQ(0, memcmp(written_data, received_data, sizeof(written_data)));
   591  }
   592  
   593  TEST_P(UnixSocketPairCmsgTest, FDPassNotCoalesced) {
   594    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   595  
   596    char sent_data1[20];
   597    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   598  
   599    auto pair1 =
   600        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   601  
   602    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair1->second_fd(),
   603                                         sent_data1, sizeof(sent_data1)));
   604  
   605    char sent_data2[20];
   606    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   607  
   608    auto pair2 =
   609        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   610  
   611    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair2->second_fd(),
   612                                         sent_data2, sizeof(sent_data2)));
   613  
   614    char received_data1[sizeof(sent_data1) + sizeof(sent_data2)];
   615    int received_fd1 = -1;
   616  
   617    RecvSingleFD(sockets->second_fd(), &received_fd1, received_data1,
   618                 sizeof(received_data1), sizeof(sent_data1));
   619  
   620    EXPECT_EQ(0, memcmp(sent_data1, received_data1, sizeof(sent_data1)));
   621    TransferTest(pair1->first_fd(), pair1->second_fd());
   622  
   623    char received_data2[sizeof(sent_data1) + sizeof(sent_data2)];
   624    int received_fd2 = -1;
   625  
   626    RecvSingleFD(sockets->second_fd(), &received_fd2, received_data2,
   627                 sizeof(received_data2), sizeof(sent_data2));
   628  
   629    EXPECT_EQ(0, memcmp(sent_data2, received_data2, sizeof(sent_data2)));
   630    TransferTest(pair2->first_fd(), pair2->second_fd());
   631  }
   632  
   633  TEST_P(UnixSocketPairCmsgTest, FDPassPeek) {
   634    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   635  
   636    char sent_data[20];
   637    RandomizeBuffer(sent_data, sizeof(sent_data));
   638  
   639    auto pair =
   640        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   641  
   642    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   643                                         sent_data, sizeof(sent_data)));
   644  
   645    char peek_data[20];
   646    int peek_fd = -1;
   647    PeekSingleFD(sockets->second_fd(), &peek_fd, peek_data, sizeof(peek_data));
   648    EXPECT_EQ(0, memcmp(sent_data, peek_data, sizeof(sent_data)));
   649    TransferTest(peek_fd, pair->first_fd());
   650    EXPECT_THAT(close(peek_fd), SyscallSucceeds());
   651  
   652    char received_data[20];
   653    int received_fd = -1;
   654    RecvSingleFD(sockets->second_fd(), &received_fd, received_data,
   655                 sizeof(received_data));
   656    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   657    TransferTest(received_fd, pair->first_fd());
   658    EXPECT_THAT(close(received_fd), SyscallSucceeds());
   659  }
   660  
   661  // A zero-length SCM_RIGHTS array should be equivalent to sending no FDs at all.
   662  TEST_P(UnixSocketPairCmsgTest, ZeroFDPass) {
   663    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   664  
   665    char sent_data[20];
   666    RandomizeBuffer(sent_data, sizeof(sent_data));
   667    ASSERT_NO_FATAL_FAILURE(
   668        SendFDs(sockets->first_fd(), nullptr, 0, sent_data, sizeof(sent_data)));
   669  
   670    char received_data[sizeof(sent_data)];
   671    ASSERT_NO_FATAL_FAILURE(
   672        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   673  
   674    EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(sent_data)));
   675  }
   676  
   677  TEST_P(UnixSocketPairCmsgTest, ZeroFDPassCoalesceData) {
   678    SKIP_IF(GetParam().type != SOCK_STREAM);
   679    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   680  
   681    char sent_data[20];
   682    RandomizeBuffer(sent_data, sizeof(sent_data));
   683    ASSERT_NO_FATAL_FAILURE(
   684        SendFDs(sockets->first_fd(), nullptr, 0, sent_data, sizeof(sent_data)));
   685    ASSERT_NO_FATAL_FAILURE(
   686        WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)));
   687  
   688    char received_data[sizeof(sent_data) * 2];
   689    ASSERT_NO_FATAL_FAILURE(
   690        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   691  
   692    EXPECT_EQ(0, memcmp(received_data, sent_data, sizeof(sent_data)));
   693    EXPECT_EQ(0, memcmp(received_data + sizeof(sent_data), sent_data,
   694                        sizeof(sent_data)));
   695  }
   696  
   697  TEST_P(UnixSocketPairCmsgTest, BasicCredPass) {
   698    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   699  
   700    char sent_data[20];
   701    RandomizeBuffer(sent_data, sizeof(sent_data));
   702  
   703    struct ucred sent_creds;
   704  
   705    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
   706    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
   707    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
   708  
   709    ASSERT_NO_FATAL_FAILURE(
   710        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
   711  
   712    SetSoPassCred(sockets->second_fd());
   713  
   714    char received_data[20];
   715    struct ucred received_creds;
   716    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   717                                      received_data, sizeof(received_data)));
   718  
   719    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   720    EXPECT_EQ(sent_creds.pid, received_creds.pid);
   721    EXPECT_EQ(sent_creds.uid, received_creds.uid);
   722    EXPECT_EQ(sent_creds.gid, received_creds.gid);
   723  }
   724  
   725  TEST_P(UnixSocketPairCmsgTest, SendNullCredsBeforeSoPassCredRecvEnd) {
   726    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   727  
   728    char sent_data[20];
   729    RandomizeBuffer(sent_data, sizeof(sent_data));
   730  
   731    ASSERT_NO_FATAL_FAILURE(
   732        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   733  
   734    SetSoPassCred(sockets->second_fd());
   735  
   736    char received_data[20];
   737    struct ucred received_creds;
   738    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   739                                      received_data, sizeof(received_data)));
   740  
   741    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   742  
   743    struct ucred want_creds {
   744      0, 65534, 65534
   745    };
   746  
   747    EXPECT_EQ(want_creds.pid, received_creds.pid);
   748    EXPECT_EQ(want_creds.uid, received_creds.uid);
   749    EXPECT_EQ(want_creds.gid, received_creds.gid);
   750  }
   751  
   752  TEST_P(UnixSocketPairCmsgTest, SendNullCredsAfterSoPassCredRecvEnd) {
   753    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   754  
   755    char sent_data[20];
   756    RandomizeBuffer(sent_data, sizeof(sent_data));
   757  
   758    SetSoPassCred(sockets->second_fd());
   759  
   760    ASSERT_NO_FATAL_FAILURE(
   761        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   762  
   763    char received_data[20];
   764    struct ucred received_creds;
   765    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   766                                      received_data, sizeof(received_data)));
   767  
   768    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   769  
   770    struct ucred want_creds;
   771    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   772    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   773    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   774  
   775    EXPECT_EQ(want_creds.pid, received_creds.pid);
   776    EXPECT_EQ(want_creds.uid, received_creds.uid);
   777    EXPECT_EQ(want_creds.gid, received_creds.gid);
   778  }
   779  
   780  TEST_P(UnixSocketPairCmsgTest, SendNullCredsBeforeSoPassCredSendEnd) {
   781    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   782  
   783    char sent_data[20];
   784    RandomizeBuffer(sent_data, sizeof(sent_data));
   785  
   786    ASSERT_NO_FATAL_FAILURE(
   787        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   788  
   789    SetSoPassCred(sockets->first_fd());
   790  
   791    char received_data[20];
   792    ASSERT_NO_FATAL_FAILURE(
   793        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   794  
   795    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   796  }
   797  
   798  TEST_P(UnixSocketPairCmsgTest, SendNullCredsAfterSoPassCredSendEnd) {
   799    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   800  
   801    char sent_data[20];
   802    RandomizeBuffer(sent_data, sizeof(sent_data));
   803  
   804    SetSoPassCred(sockets->first_fd());
   805  
   806    ASSERT_NO_FATAL_FAILURE(
   807        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   808  
   809    char received_data[20];
   810    ASSERT_NO_FATAL_FAILURE(
   811        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   812  
   813    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   814  }
   815  
   816  TEST_P(UnixSocketPairCmsgTest,
   817         SendNullCredsBeforeSoPassCredRecvEndAfterSendEnd) {
   818    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   819  
   820    char sent_data[20];
   821    RandomizeBuffer(sent_data, sizeof(sent_data));
   822  
   823    SetSoPassCred(sockets->first_fd());
   824  
   825    ASSERT_NO_FATAL_FAILURE(
   826        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   827  
   828    SetSoPassCred(sockets->second_fd());
   829  
   830    char received_data[20];
   831    struct ucred received_creds;
   832    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   833                                      received_data, sizeof(received_data)));
   834  
   835    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   836  
   837    struct ucred want_creds;
   838    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   839    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   840    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   841  
   842    EXPECT_EQ(want_creds.pid, received_creds.pid);
   843    EXPECT_EQ(want_creds.uid, received_creds.uid);
   844    EXPECT_EQ(want_creds.gid, received_creds.gid);
   845  }
   846  
   847  TEST_P(UnixSocketPairCmsgTest, WriteBeforeSoPassCredRecvEnd) {
   848    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   849  
   850    char sent_data[20];
   851    RandomizeBuffer(sent_data, sizeof(sent_data));
   852  
   853    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   854                SyscallSucceedsWithValue(sizeof(sent_data)));
   855  
   856    SetSoPassCred(sockets->second_fd());
   857  
   858    char received_data[20];
   859  
   860    struct ucred received_creds;
   861    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   862                                      received_data, sizeof(received_data)));
   863  
   864    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   865  
   866    struct ucred want_creds {
   867      0, 65534, 65534
   868    };
   869  
   870    EXPECT_EQ(want_creds.pid, received_creds.pid);
   871    EXPECT_EQ(want_creds.uid, received_creds.uid);
   872    EXPECT_EQ(want_creds.gid, received_creds.gid);
   873  }
   874  
   875  TEST_P(UnixSocketPairCmsgTest, WriteAfterSoPassCredRecvEnd) {
   876    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   877  
   878    SetSoPassCred(sockets->second_fd());
   879  
   880    char sent_data[20];
   881    RandomizeBuffer(sent_data, sizeof(sent_data));
   882    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   883                SyscallSucceedsWithValue(sizeof(sent_data)));
   884  
   885    char received_data[20];
   886  
   887    struct ucred received_creds;
   888    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   889                                      received_data, sizeof(received_data)));
   890  
   891    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   892  
   893    struct ucred want_creds;
   894    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   895    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   896    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   897  
   898    EXPECT_EQ(want_creds.pid, received_creds.pid);
   899    EXPECT_EQ(want_creds.uid, received_creds.uid);
   900    EXPECT_EQ(want_creds.gid, received_creds.gid);
   901  }
   902  
   903  TEST_P(UnixSocketPairCmsgTest, WriteBeforeSoPassCredSendEnd) {
   904    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   905  
   906    char sent_data[20];
   907    RandomizeBuffer(sent_data, sizeof(sent_data));
   908  
   909    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   910                SyscallSucceedsWithValue(sizeof(sent_data)));
   911  
   912    SetSoPassCred(sockets->first_fd());
   913  
   914    char received_data[20];
   915    ASSERT_NO_FATAL_FAILURE(
   916        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   917  
   918    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   919  }
   920  
   921  TEST_P(UnixSocketPairCmsgTest, WriteAfterSoPassCredSendEnd) {
   922    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   923  
   924    SetSoPassCred(sockets->first_fd());
   925  
   926    char sent_data[20];
   927    RandomizeBuffer(sent_data, sizeof(sent_data));
   928  
   929    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   930                SyscallSucceedsWithValue(sizeof(sent_data)));
   931  
   932    char received_data[20];
   933    ASSERT_NO_FATAL_FAILURE(
   934        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   935  
   936    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   937  }
   938  
   939  TEST_P(UnixSocketPairCmsgTest, WriteBeforeSoPassCredRecvEndAfterSendEnd) {
   940    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   941  
   942    char sent_data[20];
   943    RandomizeBuffer(sent_data, sizeof(sent_data));
   944  
   945    SetSoPassCred(sockets->first_fd());
   946  
   947    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   948                SyscallSucceedsWithValue(sizeof(sent_data)));
   949  
   950    SetSoPassCred(sockets->second_fd());
   951  
   952    char received_data[20];
   953  
   954    struct ucred received_creds;
   955    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   956                                      received_data, sizeof(received_data)));
   957  
   958    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   959  
   960    struct ucred want_creds;
   961    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   962    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   963    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   964  
   965    EXPECT_EQ(want_creds.pid, received_creds.pid);
   966    EXPECT_EQ(want_creds.uid, received_creds.uid);
   967    EXPECT_EQ(want_creds.gid, received_creds.gid);
   968  }
   969  
   970  TEST_P(UnixSocketPairCmsgTest, CredPassTruncated) {
   971    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   972  
   973    char sent_data[20];
   974    RandomizeBuffer(sent_data, sizeof(sent_data));
   975  
   976    struct ucred sent_creds;
   977  
   978    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
   979    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
   980    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
   981  
   982    ASSERT_NO_FATAL_FAILURE(
   983        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
   984  
   985    SetSoPassCred(sockets->second_fd());
   986  
   987    struct msghdr msg = {};
   988    char control[CMSG_SPACE(0) + sizeof(pid_t)];
   989    msg.msg_control = control;
   990    msg.msg_controllen = sizeof(control);
   991  
   992    char received_data[sizeof(sent_data)] = {};
   993    struct iovec iov;
   994    iov.iov_base = received_data;
   995    iov.iov_len = sizeof(received_data);
   996    msg.msg_iov = &iov;
   997    msg.msg_iovlen = 1;
   998  
   999    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1000                SyscallSucceedsWithValue(sizeof(received_data)));
  1001  
  1002    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1003  
  1004    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1005  
  1006    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1007    ASSERT_NE(cmsg, nullptr);
  1008    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
  1009    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1010    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1011  
  1012    pid_t pid = 0;
  1013    memcpy(&pid, CMSG_DATA(cmsg), sizeof(pid));
  1014    EXPECT_EQ(pid, sent_creds.pid);
  1015  }
  1016  
  1017  // CredPassNoMsgCtrunc passes a full set of credentials. It then verifies that
  1018  // receiving the full set does not result in MSG_CTRUNC being set in the msghdr.
  1019  TEST_P(UnixSocketPairCmsgTest, CredPassNoMsgCtrunc) {
  1020    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1021  
  1022    char sent_data[20];
  1023    RandomizeBuffer(sent_data, sizeof(sent_data));
  1024  
  1025    struct ucred sent_creds;
  1026  
  1027    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1028    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1029    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1030  
  1031    ASSERT_NO_FATAL_FAILURE(
  1032        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
  1033  
  1034    SetSoPassCred(sockets->second_fd());
  1035  
  1036    struct msghdr msg = {};
  1037    char control[CMSG_SPACE(sizeof(struct ucred))];
  1038    msg.msg_control = control;
  1039    msg.msg_controllen = sizeof(control);
  1040  
  1041    char received_data[sizeof(sent_data)] = {};
  1042    struct iovec iov;
  1043    iov.iov_base = received_data;
  1044    iov.iov_len = sizeof(received_data);
  1045    msg.msg_iov = &iov;
  1046    msg.msg_iovlen = 1;
  1047  
  1048    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1049                SyscallSucceedsWithValue(sizeof(received_data)));
  1050  
  1051    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1052  
  1053    // The control message should not be truncated.
  1054    EXPECT_EQ(msg.msg_flags, 0);
  1055    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1056  
  1057    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1058    ASSERT_NE(cmsg, nullptr);
  1059    EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(struct ucred)));
  1060    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1061    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1062  }
  1063  
  1064  // CredPassNoSpaceMsgCtrunc passes a full set of credentials. It then receives
  1065  // the data without providing space for any credentials and verifies that
  1066  // MSG_CTRUNC is set in the msghdr.
  1067  TEST_P(UnixSocketPairCmsgTest, CredPassNoSpaceMsgCtrunc) {
  1068    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1069  
  1070    char sent_data[20];
  1071    RandomizeBuffer(sent_data, sizeof(sent_data));
  1072  
  1073    struct ucred sent_creds;
  1074  
  1075    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1076    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1077    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1078  
  1079    ASSERT_NO_FATAL_FAILURE(
  1080        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
  1081  
  1082    SetSoPassCred(sockets->second_fd());
  1083  
  1084    struct msghdr msg = {};
  1085    char control[CMSG_SPACE(0)];
  1086    msg.msg_control = control;
  1087    msg.msg_controllen = sizeof(control);
  1088  
  1089    char received_data[sizeof(sent_data)] = {};
  1090    struct iovec iov;
  1091    iov.iov_base = received_data;
  1092    iov.iov_len = sizeof(received_data);
  1093    msg.msg_iov = &iov;
  1094    msg.msg_iovlen = 1;
  1095  
  1096    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1097                SyscallSucceedsWithValue(sizeof(received_data)));
  1098  
  1099    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1100  
  1101    // The control message should be truncated.
  1102    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
  1103    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1104  
  1105    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1106    ASSERT_NE(cmsg, nullptr);
  1107    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
  1108    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1109    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1110  }
  1111  
  1112  // CredPassTruncatedMsgCtrunc passes a full set of credentials. It then receives
  1113  // the data while providing enough space for only the first field of the
  1114  // credentials and verifies that MSG_CTRUNC is set in the msghdr.
  1115  TEST_P(UnixSocketPairCmsgTest, CredPassTruncatedMsgCtrunc) {
  1116    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1117  
  1118    char sent_data[20];
  1119    RandomizeBuffer(sent_data, sizeof(sent_data));
  1120  
  1121    struct ucred sent_creds;
  1122  
  1123    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1124    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1125    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1126  
  1127    ASSERT_NO_FATAL_FAILURE(
  1128        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
  1129  
  1130    SetSoPassCred(sockets->second_fd());
  1131  
  1132    struct msghdr msg = {};
  1133    char control[CMSG_SPACE(0) + sizeof(pid_t)];
  1134    msg.msg_control = control;
  1135    msg.msg_controllen = sizeof(control);
  1136  
  1137    char received_data[sizeof(sent_data)] = {};
  1138    struct iovec iov;
  1139    iov.iov_base = received_data;
  1140    iov.iov_len = sizeof(received_data);
  1141    msg.msg_iov = &iov;
  1142    msg.msg_iovlen = 1;
  1143  
  1144    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1145                SyscallSucceedsWithValue(sizeof(received_data)));
  1146  
  1147    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1148  
  1149    // The control message should be truncated.
  1150    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
  1151    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1152  
  1153    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1154    ASSERT_NE(cmsg, nullptr);
  1155    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
  1156    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1157    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1158  }
  1159  
  1160  TEST_P(UnixSocketPairCmsgTest, SoPassCred) {
  1161    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1162  
  1163    int opt;
  1164    socklen_t optLen = sizeof(opt);
  1165    EXPECT_THAT(
  1166        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1167        SyscallSucceeds());
  1168    EXPECT_FALSE(opt);
  1169  
  1170    optLen = sizeof(opt);
  1171    EXPECT_THAT(
  1172        getsockopt(sockets->second_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1173        SyscallSucceeds());
  1174    EXPECT_FALSE(opt);
  1175  
  1176    SetSoPassCred(sockets->first_fd());
  1177  
  1178    optLen = sizeof(opt);
  1179    EXPECT_THAT(
  1180        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1181        SyscallSucceeds());
  1182    EXPECT_TRUE(opt);
  1183  
  1184    optLen = sizeof(opt);
  1185    EXPECT_THAT(
  1186        getsockopt(sockets->second_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1187        SyscallSucceeds());
  1188    EXPECT_FALSE(opt);
  1189  
  1190    int zero = 0;
  1191    EXPECT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &zero,
  1192                           sizeof(zero)),
  1193                SyscallSucceeds());
  1194  
  1195    optLen = sizeof(opt);
  1196    EXPECT_THAT(
  1197        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1198        SyscallSucceeds());
  1199    EXPECT_FALSE(opt);
  1200  
  1201    optLen = sizeof(opt);
  1202    EXPECT_THAT(
  1203        getsockopt(sockets->second_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1204        SyscallSucceeds());
  1205    EXPECT_FALSE(opt);
  1206  }
  1207  
  1208  TEST_P(UnixSocketPairCmsgTest, NoDataCredPass) {
  1209    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1210  
  1211    char sent_data[20];
  1212    RandomizeBuffer(sent_data, sizeof(sent_data));
  1213  
  1214    struct msghdr msg = {};
  1215  
  1216    struct iovec iov;
  1217    iov.iov_base = sent_data;
  1218    iov.iov_len = sizeof(sent_data);
  1219    msg.msg_iov = &iov;
  1220    msg.msg_iovlen = 1;
  1221  
  1222    char control[CMSG_SPACE(0)];
  1223    msg.msg_control = control;
  1224    msg.msg_controllen = sizeof(control);
  1225  
  1226    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1227    cmsg->cmsg_level = SOL_SOCKET;
  1228    cmsg->cmsg_type = SCM_CREDENTIALS;
  1229    cmsg->cmsg_len = CMSG_LEN(0);
  1230  
  1231    ASSERT_THAT(RetryEINTR(sendmsg)(sockets->first_fd(), &msg, 0),
  1232                SyscallFailsWithErrno(EINVAL));
  1233  }
  1234  
  1235  TEST_P(UnixSocketPairCmsgTest, NoPassCred) {
  1236    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1237  
  1238    char sent_data[20];
  1239    RandomizeBuffer(sent_data, sizeof(sent_data));
  1240  
  1241    struct ucred sent_creds;
  1242  
  1243    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1244    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1245    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1246  
  1247    ASSERT_NO_FATAL_FAILURE(
  1248        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
  1249  
  1250    char received_data[20];
  1251  
  1252    ASSERT_NO_FATAL_FAILURE(
  1253        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
  1254  
  1255    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1256  }
  1257  
  1258  TEST_P(UnixSocketPairCmsgTest, CredAndFDPass) {
  1259    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1260  
  1261    char sent_data[20];
  1262    RandomizeBuffer(sent_data, sizeof(sent_data));
  1263  
  1264    struct ucred sent_creds;
  1265  
  1266    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1267    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1268    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1269  
  1270    auto pair =
  1271        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1272  
  1273    ASSERT_NO_FATAL_FAILURE(SendCredsAndFD(sockets->first_fd(), sent_creds,
  1274                                           pair->second_fd(), sent_data,
  1275                                           sizeof(sent_data)));
  1276  
  1277    SetSoPassCred(sockets->second_fd());
  1278  
  1279    char received_data[20];
  1280    struct ucred received_creds;
  1281    int fd = -1;
  1282    ASSERT_NO_FATAL_FAILURE(RecvCredsAndFD(sockets->second_fd(), &received_creds,
  1283                                           &fd, received_data,
  1284                                           sizeof(received_data)));
  1285  
  1286    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1287  
  1288    EXPECT_EQ(sent_creds.pid, received_creds.pid);
  1289    EXPECT_EQ(sent_creds.uid, received_creds.uid);
  1290    EXPECT_EQ(sent_creds.gid, received_creds.gid);
  1291  
  1292    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
  1293  }
  1294  
  1295  TEST_P(UnixSocketPairCmsgTest, FDPassBeforeSoPassCred) {
  1296    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1297  
  1298    char sent_data[20];
  1299    RandomizeBuffer(sent_data, sizeof(sent_data));
  1300  
  1301    auto pair =
  1302        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1303  
  1304    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1305                                         sent_data, sizeof(sent_data)));
  1306  
  1307    SetSoPassCred(sockets->second_fd());
  1308  
  1309    char received_data[20];
  1310    struct ucred received_creds;
  1311    int fd = -1;
  1312    ASSERT_NO_FATAL_FAILURE(RecvCredsAndFD(sockets->second_fd(), &received_creds,
  1313                                           &fd, received_data,
  1314                                           sizeof(received_data)));
  1315  
  1316    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1317  
  1318    struct ucred want_creds {
  1319      0, 65534, 65534
  1320    };
  1321  
  1322    EXPECT_EQ(want_creds.pid, received_creds.pid);
  1323    EXPECT_EQ(want_creds.uid, received_creds.uid);
  1324    EXPECT_EQ(want_creds.gid, received_creds.gid);
  1325  
  1326    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
  1327  }
  1328  
  1329  TEST_P(UnixSocketPairCmsgTest, FDPassAfterSoPassCred) {
  1330    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1331  
  1332    char sent_data[20];
  1333    RandomizeBuffer(sent_data, sizeof(sent_data));
  1334  
  1335    auto pair =
  1336        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1337  
  1338    SetSoPassCred(sockets->second_fd());
  1339  
  1340    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1341                                         sent_data, sizeof(sent_data)));
  1342  
  1343    char received_data[20];
  1344    struct ucred received_creds;
  1345    int fd = -1;
  1346    ASSERT_NO_FATAL_FAILURE(RecvCredsAndFD(sockets->second_fd(), &received_creds,
  1347                                           &fd, received_data,
  1348                                           sizeof(received_data)));
  1349  
  1350    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1351  
  1352    struct ucred want_creds;
  1353    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
  1354    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
  1355    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
  1356  
  1357    EXPECT_EQ(want_creds.pid, received_creds.pid);
  1358    EXPECT_EQ(want_creds.uid, received_creds.uid);
  1359    EXPECT_EQ(want_creds.gid, received_creds.gid);
  1360  
  1361    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
  1362  }
  1363  
  1364  TEST_P(UnixSocketPairCmsgTest, CloexecDroppedWhenFDPassed) {
  1365    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1366  
  1367    char sent_data[20];
  1368    RandomizeBuffer(sent_data, sizeof(sent_data));
  1369  
  1370    auto pair = ASSERT_NO_ERRNO_AND_VALUE(
  1371        UnixDomainSocketPair(SOCK_SEQPACKET | SOCK_CLOEXEC).Create());
  1372  
  1373    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1374                                         sent_data, sizeof(sent_data)));
  1375  
  1376    char received_data[20];
  1377    int fd = -1;
  1378    ASSERT_NO_FATAL_FAILURE(RecvSingleFD(sockets->second_fd(), &fd, received_data,
  1379                                         sizeof(received_data)));
  1380  
  1381    EXPECT_THAT(fcntl(fd, F_GETFD), SyscallSucceedsWithValue(0));
  1382  }
  1383  
  1384  TEST_P(UnixSocketPairCmsgTest, CloexecRecvFDPass) {
  1385    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1386  
  1387    char sent_data[20];
  1388    RandomizeBuffer(sent_data, sizeof(sent_data));
  1389  
  1390    auto pair =
  1391        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1392  
  1393    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1394                                         sent_data, sizeof(sent_data)));
  1395  
  1396    struct msghdr msg = {};
  1397    char control[CMSG_SPACE(sizeof(int))];
  1398    msg.msg_control = control;
  1399    msg.msg_controllen = sizeof(control);
  1400  
  1401    struct iovec iov;
  1402    char received_data[20];
  1403    iov.iov_base = received_data;
  1404    iov.iov_len = sizeof(received_data);
  1405    msg.msg_iov = &iov;
  1406    msg.msg_iovlen = 1;
  1407  
  1408    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_CMSG_CLOEXEC),
  1409                SyscallSucceedsWithValue(sizeof(received_data)));
  1410    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1411    ASSERT_NE(cmsg, nullptr);
  1412    ASSERT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
  1413    ASSERT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1414    ASSERT_EQ(cmsg->cmsg_type, SCM_RIGHTS);
  1415  
  1416    int fd = -1;
  1417    memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
  1418  
  1419    EXPECT_THAT(fcntl(fd, F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC));
  1420  }
  1421  
  1422  TEST_P(UnixSocketPairCmsgTest, FDPassAfterSoPassCredWithoutCredSpace) {
  1423    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1424  
  1425    char sent_data[20];
  1426    RandomizeBuffer(sent_data, sizeof(sent_data));
  1427  
  1428    auto pair =
  1429        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1430  
  1431    SetSoPassCred(sockets->second_fd());
  1432  
  1433    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1434                                         sent_data, sizeof(sent_data)));
  1435  
  1436    struct msghdr msg = {};
  1437    char control[CMSG_LEN(0)];
  1438    msg.msg_control = control;
  1439    msg.msg_controllen = sizeof(control);
  1440  
  1441    char received_data[20];
  1442    struct iovec iov;
  1443    iov.iov_base = received_data;
  1444    iov.iov_len = sizeof(received_data);
  1445    msg.msg_iov = &iov;
  1446    msg.msg_iovlen = 1;
  1447  
  1448    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1449                SyscallSucceedsWithValue(sizeof(received_data)));
  1450  
  1451    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1452  
  1453    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1454  
  1455    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1456    ASSERT_NE(cmsg, nullptr);
  1457    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
  1458    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1459    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1460  }
  1461  
  1462  TEST_P(UnixSocketPairCmsgTest, InheritPasscred) {
  1463    // Create an abstract server, but set SO_PASSCRED on it
  1464    struct sockaddr_un bind_addr =
  1465        ASSERT_NO_ERRNO_AND_VALUE(UniqueUnixAddr(true, AF_UNIX));
  1466    auto bound = ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_UNIX, SOCK_STREAM, 0));
  1467    SetSoPassCred(bound.get());
  1468    ASSERT_THAT(bind(bound.get(), AsSockAddr(&bind_addr), sizeof(bind_addr)),
  1469                SyscallSucceeds());
  1470    ASSERT_THAT(listen(bound.get(),
  1471                       /* backlog = */ 5),  // NOLINT(bugprone-argument-comment)
  1472                SyscallSucceeds());
  1473  
  1474    // Create a connected socket pair using the server
  1475    auto connected = ASSERT_NO_ERRNO_AND_VALUE(Socket(AF_UNIX, SOCK_STREAM, 0));
  1476    ASSERT_THAT(
  1477        connect(connected.get(), AsSockAddr(&bind_addr), sizeof(bind_addr)),
  1478        SyscallSucceeds());
  1479    auto accepted =
  1480        ASSERT_NO_ERRNO_AND_VALUE(Accept4(bound.get(), nullptr, nullptr, 0));
  1481    ASSERT_THAT(close(bound.release()), SyscallSucceeds());
  1482  
  1483    // The accepted socket should have SO_PASSCRED set
  1484    int opt;
  1485    socklen_t optLen = sizeof(opt);
  1486    EXPECT_THAT(
  1487        getsockopt(accepted.get(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1488        SyscallSucceeds());
  1489    EXPECT_TRUE(opt);
  1490  }
  1491  
  1492  // This test will validate that MSG_CTRUNC as an input flag to recvmsg will
  1493  // not appear as an output flag on the control message when truncation doesn't
  1494  // happen.
  1495  TEST_P(UnixSocketPairCmsgTest, MsgCtruncInputIsNoop) {
  1496    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1497  
  1498    char sent_data[20];
  1499    RandomizeBuffer(sent_data, sizeof(sent_data));
  1500  
  1501    auto pair =
  1502        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1503  
  1504    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1505                                         sent_data, sizeof(sent_data)));
  1506  
  1507    struct msghdr msg = {};
  1508    char control[CMSG_SPACE(sizeof(int)) /* we're passing a single fd */];
  1509    msg.msg_control = control;
  1510    msg.msg_controllen = sizeof(control);
  1511  
  1512    struct iovec iov;
  1513    char received_data[20];
  1514    iov.iov_base = received_data;
  1515    iov.iov_len = sizeof(received_data);
  1516    msg.msg_iov = &iov;
  1517    msg.msg_iovlen = 1;
  1518  
  1519    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_CTRUNC),
  1520                SyscallSucceedsWithValue(sizeof(received_data)));
  1521    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1522    ASSERT_NE(cmsg, nullptr);
  1523    ASSERT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
  1524    ASSERT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1525    ASSERT_EQ(cmsg->cmsg_type, SCM_RIGHTS);
  1526  
  1527    // Now we should verify that MSG_CTRUNC wasn't set as an output flag.
  1528    EXPECT_EQ(msg.msg_flags & MSG_CTRUNC, 0);
  1529  }
  1530  
  1531  TEST_P(UnixSocketPairCmsgTest, FDPassAfterSoPassCredWithoutCredHeaderSpace) {
  1532    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1533  
  1534    char sent_data[20];
  1535    RandomizeBuffer(sent_data, sizeof(sent_data));
  1536  
  1537    auto pair =
  1538        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1539  
  1540    SetSoPassCred(sockets->second_fd());
  1541  
  1542    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1543                                         sent_data, sizeof(sent_data)));
  1544  
  1545    struct msghdr msg = {};
  1546    char control[CMSG_LEN(0) / 2];
  1547    msg.msg_control = control;
  1548    msg.msg_controllen = sizeof(control);
  1549  
  1550    char received_data[20];
  1551    struct iovec iov;
  1552    iov.iov_base = received_data;
  1553    iov.iov_len = sizeof(received_data);
  1554    msg.msg_iov = &iov;
  1555    msg.msg_iovlen = 1;
  1556  
  1557    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1558                SyscallSucceedsWithValue(sizeof(received_data)));
  1559  
  1560    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1561    EXPECT_EQ(msg.msg_controllen, 0);
  1562  }
  1563  
  1564  }  // namespace
  1565  
  1566  }  // namespace testing
  1567  }  // namespace gvisor