github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/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/socket_test_util.h"
    30  #include "test/syscalls/linux/unix_domain_socket_test_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  TEST_P(UnixSocketPairCmsgTest, BasicCredPass) {
   662    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   663  
   664    char sent_data[20];
   665    RandomizeBuffer(sent_data, sizeof(sent_data));
   666  
   667    struct ucred sent_creds;
   668  
   669    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
   670    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
   671    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
   672  
   673    ASSERT_NO_FATAL_FAILURE(
   674        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
   675  
   676    SetSoPassCred(sockets->second_fd());
   677  
   678    char received_data[20];
   679    struct ucred received_creds;
   680    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   681                                      received_data, sizeof(received_data)));
   682  
   683    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   684    EXPECT_EQ(sent_creds.pid, received_creds.pid);
   685    EXPECT_EQ(sent_creds.uid, received_creds.uid);
   686    EXPECT_EQ(sent_creds.gid, received_creds.gid);
   687  }
   688  
   689  TEST_P(UnixSocketPairCmsgTest, SendNullCredsBeforeSoPassCredRecvEnd) {
   690    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   691  
   692    char sent_data[20];
   693    RandomizeBuffer(sent_data, sizeof(sent_data));
   694  
   695    ASSERT_NO_FATAL_FAILURE(
   696        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   697  
   698    SetSoPassCred(sockets->second_fd());
   699  
   700    char received_data[20];
   701    struct ucred received_creds;
   702    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   703                                      received_data, sizeof(received_data)));
   704  
   705    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   706  
   707    struct ucred want_creds {
   708      0, 65534, 65534
   709    };
   710  
   711    EXPECT_EQ(want_creds.pid, received_creds.pid);
   712    EXPECT_EQ(want_creds.uid, received_creds.uid);
   713    EXPECT_EQ(want_creds.gid, received_creds.gid);
   714  }
   715  
   716  TEST_P(UnixSocketPairCmsgTest, SendNullCredsAfterSoPassCredRecvEnd) {
   717    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   718  
   719    char sent_data[20];
   720    RandomizeBuffer(sent_data, sizeof(sent_data));
   721  
   722    SetSoPassCred(sockets->second_fd());
   723  
   724    ASSERT_NO_FATAL_FAILURE(
   725        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   726  
   727    char received_data[20];
   728    struct ucred received_creds;
   729    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   730                                      received_data, sizeof(received_data)));
   731  
   732    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   733  
   734    struct ucred want_creds;
   735    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   736    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   737    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   738  
   739    EXPECT_EQ(want_creds.pid, received_creds.pid);
   740    EXPECT_EQ(want_creds.uid, received_creds.uid);
   741    EXPECT_EQ(want_creds.gid, received_creds.gid);
   742  }
   743  
   744  TEST_P(UnixSocketPairCmsgTest, SendNullCredsBeforeSoPassCredSendEnd) {
   745    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   746  
   747    char sent_data[20];
   748    RandomizeBuffer(sent_data, sizeof(sent_data));
   749  
   750    ASSERT_NO_FATAL_FAILURE(
   751        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   752  
   753    SetSoPassCred(sockets->first_fd());
   754  
   755    char received_data[20];
   756    ASSERT_NO_FATAL_FAILURE(
   757        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   758  
   759    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   760  }
   761  
   762  TEST_P(UnixSocketPairCmsgTest, SendNullCredsAfterSoPassCredSendEnd) {
   763    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   764  
   765    char sent_data[20];
   766    RandomizeBuffer(sent_data, sizeof(sent_data));
   767  
   768    SetSoPassCred(sockets->first_fd());
   769  
   770    ASSERT_NO_FATAL_FAILURE(
   771        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   772  
   773    char received_data[20];
   774    ASSERT_NO_FATAL_FAILURE(
   775        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   776  
   777    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   778  }
   779  
   780  TEST_P(UnixSocketPairCmsgTest,
   781         SendNullCredsBeforeSoPassCredRecvEndAfterSendEnd) {
   782    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   783  
   784    char sent_data[20];
   785    RandomizeBuffer(sent_data, sizeof(sent_data));
   786  
   787    SetSoPassCred(sockets->first_fd());
   788  
   789    ASSERT_NO_FATAL_FAILURE(
   790        SendNullCmsg(sockets->first_fd(), sent_data, sizeof(sent_data)));
   791  
   792    SetSoPassCred(sockets->second_fd());
   793  
   794    char received_data[20];
   795    struct ucred received_creds;
   796    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   797                                      received_data, sizeof(received_data)));
   798  
   799    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   800  
   801    struct ucred want_creds;
   802    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   803    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   804    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   805  
   806    EXPECT_EQ(want_creds.pid, received_creds.pid);
   807    EXPECT_EQ(want_creds.uid, received_creds.uid);
   808    EXPECT_EQ(want_creds.gid, received_creds.gid);
   809  }
   810  
   811  TEST_P(UnixSocketPairCmsgTest, WriteBeforeSoPassCredRecvEnd) {
   812    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   813  
   814    char sent_data[20];
   815    RandomizeBuffer(sent_data, sizeof(sent_data));
   816  
   817    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   818                SyscallSucceedsWithValue(sizeof(sent_data)));
   819  
   820    SetSoPassCred(sockets->second_fd());
   821  
   822    char received_data[20];
   823  
   824    struct ucred received_creds;
   825    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   826                                      received_data, sizeof(received_data)));
   827  
   828    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   829  
   830    struct ucred want_creds {
   831      0, 65534, 65534
   832    };
   833  
   834    EXPECT_EQ(want_creds.pid, received_creds.pid);
   835    EXPECT_EQ(want_creds.uid, received_creds.uid);
   836    EXPECT_EQ(want_creds.gid, received_creds.gid);
   837  }
   838  
   839  TEST_P(UnixSocketPairCmsgTest, WriteAfterSoPassCredRecvEnd) {
   840    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   841  
   842    SetSoPassCred(sockets->second_fd());
   843  
   844    char sent_data[20];
   845    RandomizeBuffer(sent_data, sizeof(sent_data));
   846    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   847                SyscallSucceedsWithValue(sizeof(sent_data)));
   848  
   849    char received_data[20];
   850  
   851    struct ucred received_creds;
   852    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   853                                      received_data, sizeof(received_data)));
   854  
   855    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   856  
   857    struct ucred want_creds;
   858    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   859    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   860    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   861  
   862    EXPECT_EQ(want_creds.pid, received_creds.pid);
   863    EXPECT_EQ(want_creds.uid, received_creds.uid);
   864    EXPECT_EQ(want_creds.gid, received_creds.gid);
   865  }
   866  
   867  TEST_P(UnixSocketPairCmsgTest, WriteBeforeSoPassCredSendEnd) {
   868    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   869  
   870    char sent_data[20];
   871    RandomizeBuffer(sent_data, sizeof(sent_data));
   872  
   873    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   874                SyscallSucceedsWithValue(sizeof(sent_data)));
   875  
   876    SetSoPassCred(sockets->first_fd());
   877  
   878    char received_data[20];
   879    ASSERT_NO_FATAL_FAILURE(
   880        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   881  
   882    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   883  }
   884  
   885  TEST_P(UnixSocketPairCmsgTest, WriteAfterSoPassCredSendEnd) {
   886    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   887  
   888    SetSoPassCred(sockets->first_fd());
   889  
   890    char sent_data[20];
   891    RandomizeBuffer(sent_data, sizeof(sent_data));
   892  
   893    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   894                SyscallSucceedsWithValue(sizeof(sent_data)));
   895  
   896    char received_data[20];
   897    ASSERT_NO_FATAL_FAILURE(
   898        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   899  
   900    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   901  }
   902  
   903  TEST_P(UnixSocketPairCmsgTest, WriteBeforeSoPassCredRecvEndAfterSendEnd) {
   904    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   905  
   906    char sent_data[20];
   907    RandomizeBuffer(sent_data, sizeof(sent_data));
   908  
   909    SetSoPassCred(sockets->first_fd());
   910  
   911    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data)),
   912                SyscallSucceedsWithValue(sizeof(sent_data)));
   913  
   914    SetSoPassCred(sockets->second_fd());
   915  
   916    char received_data[20];
   917  
   918    struct ucred received_creds;
   919    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   920                                      received_data, sizeof(received_data)));
   921  
   922    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   923  
   924    struct ucred want_creds;
   925    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   926    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   927    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   928  
   929    EXPECT_EQ(want_creds.pid, received_creds.pid);
   930    EXPECT_EQ(want_creds.uid, received_creds.uid);
   931    EXPECT_EQ(want_creds.gid, received_creds.gid);
   932  }
   933  
   934  TEST_P(UnixSocketPairCmsgTest, CredPassTruncated) {
   935    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   936  
   937    char sent_data[20];
   938    RandomizeBuffer(sent_data, sizeof(sent_data));
   939  
   940    struct ucred sent_creds;
   941  
   942    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
   943    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
   944    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
   945  
   946    ASSERT_NO_FATAL_FAILURE(
   947        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
   948  
   949    SetSoPassCred(sockets->second_fd());
   950  
   951    struct msghdr msg = {};
   952    char control[CMSG_SPACE(0) + sizeof(pid_t)];
   953    msg.msg_control = control;
   954    msg.msg_controllen = sizeof(control);
   955  
   956    char received_data[sizeof(sent_data)] = {};
   957    struct iovec iov;
   958    iov.iov_base = received_data;
   959    iov.iov_len = sizeof(received_data);
   960    msg.msg_iov = &iov;
   961    msg.msg_iovlen = 1;
   962  
   963    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
   964                SyscallSucceedsWithValue(sizeof(received_data)));
   965  
   966    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   967  
   968    EXPECT_EQ(msg.msg_controllen, sizeof(control));
   969  
   970    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
   971    ASSERT_NE(cmsg, nullptr);
   972    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
   973    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
   974    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
   975  
   976    pid_t pid = 0;
   977    memcpy(&pid, CMSG_DATA(cmsg), sizeof(pid));
   978    EXPECT_EQ(pid, sent_creds.pid);
   979  }
   980  
   981  // CredPassNoMsgCtrunc passes a full set of credentials. It then verifies that
   982  // receiving the full set does not result in MSG_CTRUNC being set in the msghdr.
   983  TEST_P(UnixSocketPairCmsgTest, CredPassNoMsgCtrunc) {
   984    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   985  
   986    char sent_data[20];
   987    RandomizeBuffer(sent_data, sizeof(sent_data));
   988  
   989    struct ucred sent_creds;
   990  
   991    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
   992    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
   993    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
   994  
   995    ASSERT_NO_FATAL_FAILURE(
   996        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
   997  
   998    SetSoPassCred(sockets->second_fd());
   999  
  1000    struct msghdr msg = {};
  1001    char control[CMSG_SPACE(sizeof(struct ucred))];
  1002    msg.msg_control = control;
  1003    msg.msg_controllen = sizeof(control);
  1004  
  1005    char received_data[sizeof(sent_data)] = {};
  1006    struct iovec iov;
  1007    iov.iov_base = received_data;
  1008    iov.iov_len = sizeof(received_data);
  1009    msg.msg_iov = &iov;
  1010    msg.msg_iovlen = 1;
  1011  
  1012    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1013                SyscallSucceedsWithValue(sizeof(received_data)));
  1014  
  1015    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1016  
  1017    // The control message should not be truncated.
  1018    EXPECT_EQ(msg.msg_flags, 0);
  1019    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1020  
  1021    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1022    ASSERT_NE(cmsg, nullptr);
  1023    EXPECT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(struct ucred)));
  1024    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1025    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1026  }
  1027  
  1028  // CredPassNoSpaceMsgCtrunc passes a full set of credentials. It then receives
  1029  // the data without providing space for any credentials and verifies that
  1030  // MSG_CTRUNC is set in the msghdr.
  1031  TEST_P(UnixSocketPairCmsgTest, CredPassNoSpaceMsgCtrunc) {
  1032    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1033  
  1034    char sent_data[20];
  1035    RandomizeBuffer(sent_data, sizeof(sent_data));
  1036  
  1037    struct ucred sent_creds;
  1038  
  1039    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1040    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1041    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1042  
  1043    ASSERT_NO_FATAL_FAILURE(
  1044        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
  1045  
  1046    SetSoPassCred(sockets->second_fd());
  1047  
  1048    struct msghdr msg = {};
  1049    char control[CMSG_SPACE(0)];
  1050    msg.msg_control = control;
  1051    msg.msg_controllen = sizeof(control);
  1052  
  1053    char received_data[sizeof(sent_data)] = {};
  1054    struct iovec iov;
  1055    iov.iov_base = received_data;
  1056    iov.iov_len = sizeof(received_data);
  1057    msg.msg_iov = &iov;
  1058    msg.msg_iovlen = 1;
  1059  
  1060    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1061                SyscallSucceedsWithValue(sizeof(received_data)));
  1062  
  1063    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1064  
  1065    // The control message should be truncated.
  1066    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
  1067    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1068  
  1069    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1070    ASSERT_NE(cmsg, nullptr);
  1071    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
  1072    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1073    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1074  }
  1075  
  1076  // CredPassTruncatedMsgCtrunc passes a full set of credentials. It then receives
  1077  // the data while providing enough space for only the first field of the
  1078  // credentials and verifies that MSG_CTRUNC is set in the msghdr.
  1079  TEST_P(UnixSocketPairCmsgTest, CredPassTruncatedMsgCtrunc) {
  1080    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1081  
  1082    char sent_data[20];
  1083    RandomizeBuffer(sent_data, sizeof(sent_data));
  1084  
  1085    struct ucred sent_creds;
  1086  
  1087    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1088    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1089    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1090  
  1091    ASSERT_NO_FATAL_FAILURE(
  1092        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
  1093  
  1094    SetSoPassCred(sockets->second_fd());
  1095  
  1096    struct msghdr msg = {};
  1097    char control[CMSG_SPACE(0) + sizeof(pid_t)];
  1098    msg.msg_control = control;
  1099    msg.msg_controllen = sizeof(control);
  1100  
  1101    char received_data[sizeof(sent_data)] = {};
  1102    struct iovec iov;
  1103    iov.iov_base = received_data;
  1104    iov.iov_len = sizeof(received_data);
  1105    msg.msg_iov = &iov;
  1106    msg.msg_iovlen = 1;
  1107  
  1108    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1109                SyscallSucceedsWithValue(sizeof(received_data)));
  1110  
  1111    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1112  
  1113    // The control message should be truncated.
  1114    EXPECT_EQ(msg.msg_flags, MSG_CTRUNC);
  1115    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1116  
  1117    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1118    ASSERT_NE(cmsg, nullptr);
  1119    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
  1120    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1121    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1122  }
  1123  
  1124  TEST_P(UnixSocketPairCmsgTest, SoPassCred) {
  1125    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1126  
  1127    int opt;
  1128    socklen_t optLen = sizeof(opt);
  1129    EXPECT_THAT(
  1130        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1131        SyscallSucceeds());
  1132    EXPECT_FALSE(opt);
  1133  
  1134    optLen = sizeof(opt);
  1135    EXPECT_THAT(
  1136        getsockopt(sockets->second_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1137        SyscallSucceeds());
  1138    EXPECT_FALSE(opt);
  1139  
  1140    SetSoPassCred(sockets->first_fd());
  1141  
  1142    optLen = sizeof(opt);
  1143    EXPECT_THAT(
  1144        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1145        SyscallSucceeds());
  1146    EXPECT_TRUE(opt);
  1147  
  1148    optLen = sizeof(opt);
  1149    EXPECT_THAT(
  1150        getsockopt(sockets->second_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1151        SyscallSucceeds());
  1152    EXPECT_FALSE(opt);
  1153  
  1154    int zero = 0;
  1155    EXPECT_THAT(setsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &zero,
  1156                           sizeof(zero)),
  1157                SyscallSucceeds());
  1158  
  1159    optLen = sizeof(opt);
  1160    EXPECT_THAT(
  1161        getsockopt(sockets->first_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1162        SyscallSucceeds());
  1163    EXPECT_FALSE(opt);
  1164  
  1165    optLen = sizeof(opt);
  1166    EXPECT_THAT(
  1167        getsockopt(sockets->second_fd(), SOL_SOCKET, SO_PASSCRED, &opt, &optLen),
  1168        SyscallSucceeds());
  1169    EXPECT_FALSE(opt);
  1170  }
  1171  
  1172  TEST_P(UnixSocketPairCmsgTest, NoDataCredPass) {
  1173    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1174  
  1175    char sent_data[20];
  1176    RandomizeBuffer(sent_data, sizeof(sent_data));
  1177  
  1178    struct msghdr msg = {};
  1179  
  1180    struct iovec iov;
  1181    iov.iov_base = sent_data;
  1182    iov.iov_len = sizeof(sent_data);
  1183    msg.msg_iov = &iov;
  1184    msg.msg_iovlen = 1;
  1185  
  1186    char control[CMSG_SPACE(0)];
  1187    msg.msg_control = control;
  1188    msg.msg_controllen = sizeof(control);
  1189  
  1190    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1191    cmsg->cmsg_level = SOL_SOCKET;
  1192    cmsg->cmsg_type = SCM_CREDENTIALS;
  1193    cmsg->cmsg_len = CMSG_LEN(0);
  1194  
  1195    ASSERT_THAT(RetryEINTR(sendmsg)(sockets->first_fd(), &msg, 0),
  1196                SyscallFailsWithErrno(EINVAL));
  1197  }
  1198  
  1199  TEST_P(UnixSocketPairCmsgTest, NoPassCred) {
  1200    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1201  
  1202    char sent_data[20];
  1203    RandomizeBuffer(sent_data, sizeof(sent_data));
  1204  
  1205    struct ucred sent_creds;
  1206  
  1207    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1208    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1209    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1210  
  1211    ASSERT_NO_FATAL_FAILURE(
  1212        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
  1213  
  1214    char received_data[20];
  1215  
  1216    ASSERT_NO_FATAL_FAILURE(
  1217        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
  1218  
  1219    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1220  }
  1221  
  1222  TEST_P(UnixSocketPairCmsgTest, CredAndFDPass) {
  1223    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1224  
  1225    char sent_data[20];
  1226    RandomizeBuffer(sent_data, sizeof(sent_data));
  1227  
  1228    struct ucred sent_creds;
  1229  
  1230    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
  1231    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
  1232    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
  1233  
  1234    auto pair =
  1235        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1236  
  1237    ASSERT_NO_FATAL_FAILURE(SendCredsAndFD(sockets->first_fd(), sent_creds,
  1238                                           pair->second_fd(), sent_data,
  1239                                           sizeof(sent_data)));
  1240  
  1241    SetSoPassCred(sockets->second_fd());
  1242  
  1243    char received_data[20];
  1244    struct ucred received_creds;
  1245    int fd = -1;
  1246    ASSERT_NO_FATAL_FAILURE(RecvCredsAndFD(sockets->second_fd(), &received_creds,
  1247                                           &fd, received_data,
  1248                                           sizeof(received_data)));
  1249  
  1250    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1251  
  1252    EXPECT_EQ(sent_creds.pid, received_creds.pid);
  1253    EXPECT_EQ(sent_creds.uid, received_creds.uid);
  1254    EXPECT_EQ(sent_creds.gid, received_creds.gid);
  1255  
  1256    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
  1257  }
  1258  
  1259  TEST_P(UnixSocketPairCmsgTest, FDPassBeforeSoPassCred) {
  1260    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1261  
  1262    char sent_data[20];
  1263    RandomizeBuffer(sent_data, sizeof(sent_data));
  1264  
  1265    auto pair =
  1266        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1267  
  1268    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1269                                         sent_data, sizeof(sent_data)));
  1270  
  1271    SetSoPassCred(sockets->second_fd());
  1272  
  1273    char received_data[20];
  1274    struct ucred received_creds;
  1275    int fd = -1;
  1276    ASSERT_NO_FATAL_FAILURE(RecvCredsAndFD(sockets->second_fd(), &received_creds,
  1277                                           &fd, received_data,
  1278                                           sizeof(received_data)));
  1279  
  1280    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1281  
  1282    struct ucred want_creds {
  1283      0, 65534, 65534
  1284    };
  1285  
  1286    EXPECT_EQ(want_creds.pid, received_creds.pid);
  1287    EXPECT_EQ(want_creds.uid, received_creds.uid);
  1288    EXPECT_EQ(want_creds.gid, received_creds.gid);
  1289  
  1290    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
  1291  }
  1292  
  1293  TEST_P(UnixSocketPairCmsgTest, FDPassAfterSoPassCred) {
  1294    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1295  
  1296    char sent_data[20];
  1297    RandomizeBuffer(sent_data, sizeof(sent_data));
  1298  
  1299    auto pair =
  1300        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1301  
  1302    SetSoPassCred(sockets->second_fd());
  1303  
  1304    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1305                                         sent_data, sizeof(sent_data)));
  1306  
  1307    char received_data[20];
  1308    struct ucred received_creds;
  1309    int fd = -1;
  1310    ASSERT_NO_FATAL_FAILURE(RecvCredsAndFD(sockets->second_fd(), &received_creds,
  1311                                           &fd, received_data,
  1312                                           sizeof(received_data)));
  1313  
  1314    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1315  
  1316    struct ucred want_creds;
  1317    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
  1318    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
  1319    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
  1320  
  1321    EXPECT_EQ(want_creds.pid, received_creds.pid);
  1322    EXPECT_EQ(want_creds.uid, received_creds.uid);
  1323    EXPECT_EQ(want_creds.gid, received_creds.gid);
  1324  
  1325    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
  1326  }
  1327  
  1328  TEST_P(UnixSocketPairCmsgTest, CloexecDroppedWhenFDPassed) {
  1329    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1330  
  1331    char sent_data[20];
  1332    RandomizeBuffer(sent_data, sizeof(sent_data));
  1333  
  1334    auto pair = ASSERT_NO_ERRNO_AND_VALUE(
  1335        UnixDomainSocketPair(SOCK_SEQPACKET | SOCK_CLOEXEC).Create());
  1336  
  1337    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1338                                         sent_data, sizeof(sent_data)));
  1339  
  1340    char received_data[20];
  1341    int fd = -1;
  1342    ASSERT_NO_FATAL_FAILURE(RecvSingleFD(sockets->second_fd(), &fd, received_data,
  1343                                         sizeof(received_data)));
  1344  
  1345    EXPECT_THAT(fcntl(fd, F_GETFD), SyscallSucceedsWithValue(0));
  1346  }
  1347  
  1348  TEST_P(UnixSocketPairCmsgTest, CloexecRecvFDPass) {
  1349    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1350  
  1351    char sent_data[20];
  1352    RandomizeBuffer(sent_data, sizeof(sent_data));
  1353  
  1354    auto pair =
  1355        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1356  
  1357    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1358                                         sent_data, sizeof(sent_data)));
  1359  
  1360    struct msghdr msg = {};
  1361    char control[CMSG_SPACE(sizeof(int))];
  1362    msg.msg_control = control;
  1363    msg.msg_controllen = sizeof(control);
  1364  
  1365    struct iovec iov;
  1366    char received_data[20];
  1367    iov.iov_base = received_data;
  1368    iov.iov_len = sizeof(received_data);
  1369    msg.msg_iov = &iov;
  1370    msg.msg_iovlen = 1;
  1371  
  1372    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_CMSG_CLOEXEC),
  1373                SyscallSucceedsWithValue(sizeof(received_data)));
  1374    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1375    ASSERT_NE(cmsg, nullptr);
  1376    ASSERT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
  1377    ASSERT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1378    ASSERT_EQ(cmsg->cmsg_type, SCM_RIGHTS);
  1379  
  1380    int fd = -1;
  1381    memcpy(&fd, CMSG_DATA(cmsg), sizeof(int));
  1382  
  1383    EXPECT_THAT(fcntl(fd, F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC));
  1384  }
  1385  
  1386  TEST_P(UnixSocketPairCmsgTest, FDPassAfterSoPassCredWithoutCredSpace) {
  1387    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1388  
  1389    char sent_data[20];
  1390    RandomizeBuffer(sent_data, sizeof(sent_data));
  1391  
  1392    auto pair =
  1393        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1394  
  1395    SetSoPassCred(sockets->second_fd());
  1396  
  1397    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1398                                         sent_data, sizeof(sent_data)));
  1399  
  1400    struct msghdr msg = {};
  1401    char control[CMSG_LEN(0)];
  1402    msg.msg_control = control;
  1403    msg.msg_controllen = sizeof(control);
  1404  
  1405    char received_data[20];
  1406    struct iovec iov;
  1407    iov.iov_base = received_data;
  1408    iov.iov_len = sizeof(received_data);
  1409    msg.msg_iov = &iov;
  1410    msg.msg_iovlen = 1;
  1411  
  1412    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1413                SyscallSucceedsWithValue(sizeof(received_data)));
  1414  
  1415    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1416  
  1417    EXPECT_EQ(msg.msg_controllen, sizeof(control));
  1418  
  1419    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1420    ASSERT_NE(cmsg, nullptr);
  1421    EXPECT_EQ(cmsg->cmsg_len, sizeof(control));
  1422    EXPECT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1423    EXPECT_EQ(cmsg->cmsg_type, SCM_CREDENTIALS);
  1424  }
  1425  
  1426  // This test will validate that MSG_CTRUNC as an input flag to recvmsg will
  1427  // not appear as an output flag on the control message when truncation doesn't
  1428  // happen.
  1429  TEST_P(UnixSocketPairCmsgTest, MsgCtruncInputIsNoop) {
  1430    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1431  
  1432    char sent_data[20];
  1433    RandomizeBuffer(sent_data, sizeof(sent_data));
  1434  
  1435    auto pair =
  1436        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1437  
  1438    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1439                                         sent_data, sizeof(sent_data)));
  1440  
  1441    struct msghdr msg = {};
  1442    char control[CMSG_SPACE(sizeof(int)) /* we're passing a single fd */];
  1443    msg.msg_control = control;
  1444    msg.msg_controllen = sizeof(control);
  1445  
  1446    struct iovec iov;
  1447    char received_data[20];
  1448    iov.iov_base = received_data;
  1449    iov.iov_len = sizeof(received_data);
  1450    msg.msg_iov = &iov;
  1451    msg.msg_iovlen = 1;
  1452  
  1453    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, MSG_CTRUNC),
  1454                SyscallSucceedsWithValue(sizeof(received_data)));
  1455    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
  1456    ASSERT_NE(cmsg, nullptr);
  1457    ASSERT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(int)));
  1458    ASSERT_EQ(cmsg->cmsg_level, SOL_SOCKET);
  1459    ASSERT_EQ(cmsg->cmsg_type, SCM_RIGHTS);
  1460  
  1461    // Now we should verify that MSG_CTRUNC wasn't set as an output flag.
  1462    EXPECT_EQ(msg.msg_flags & MSG_CTRUNC, 0);
  1463  }
  1464  
  1465  TEST_P(UnixSocketPairCmsgTest, FDPassAfterSoPassCredWithoutCredHeaderSpace) {
  1466    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
  1467  
  1468    char sent_data[20];
  1469    RandomizeBuffer(sent_data, sizeof(sent_data));
  1470  
  1471    auto pair =
  1472        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
  1473  
  1474    SetSoPassCred(sockets->second_fd());
  1475  
  1476    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
  1477                                         sent_data, sizeof(sent_data)));
  1478  
  1479    struct msghdr msg = {};
  1480    char control[CMSG_LEN(0) / 2];
  1481    msg.msg_control = control;
  1482    msg.msg_controllen = sizeof(control);
  1483  
  1484    char received_data[20];
  1485    struct iovec iov;
  1486    iov.iov_base = received_data;
  1487    iov.iov_len = sizeof(received_data);
  1488    msg.msg_iov = &iov;
  1489    msg.msg_iovlen = 1;
  1490  
  1491    ASSERT_THAT(RetryEINTR(recvmsg)(sockets->second_fd(), &msg, 0),
  1492                SyscallSucceedsWithValue(sizeof(received_data)));
  1493  
  1494    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
  1495    EXPECT_EQ(msg.msg_controllen, 0);
  1496  }
  1497  
  1498  }  // namespace
  1499  
  1500  }  // namespace testing
  1501  }  // namespace gvisor