github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/socket_unix_unbound_stream.cc (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include <stdio.h>
    16  #include <sys/un.h>
    17  
    18  #include "gtest/gtest.h"
    19  #include "test/syscalls/linux/socket_test_util.h"
    20  #include "test/syscalls/linux/unix_domain_socket_test_util.h"
    21  #include "test/util/test_util.h"
    22  
    23  namespace gvisor {
    24  namespace testing {
    25  
    26  namespace {
    27  
    28  // Test fixture for tests that apply to pairs of connected unix stream sockets.
    29  using UnixStreamSocketPairTest = SocketPairTest;
    30  
    31  // FDPassPartialRead checks that sent control messages cannot be read after
    32  // any of their associated data has been read while ignoring the control message
    33  // by using read(2) instead of recvmsg(2).
    34  TEST_P(UnixStreamSocketPairTest, FDPassPartialRead) {
    35    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    36  
    37    char sent_data[20];
    38    RandomizeBuffer(sent_data, sizeof(sent_data));
    39  
    40    auto pair =
    41        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
    42  
    43    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
    44                                         sent_data, sizeof(sent_data)));
    45  
    46    char received_data[sizeof(sent_data) / 2];
    47    ASSERT_THAT(
    48        ReadFd(sockets->second_fd(), received_data, sizeof(received_data)),
    49        SyscallSucceedsWithValue(sizeof(received_data)));
    50  
    51    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(received_data)));
    52  
    53    RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data));
    54    EXPECT_EQ(0, memcmp(sent_data + sizeof(received_data), received_data,
    55                        sizeof(received_data)));
    56  }
    57  
    58  TEST_P(UnixStreamSocketPairTest, FDPassCoalescedRead) {
    59    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    60  
    61    char sent_data1[20];
    62    RandomizeBuffer(sent_data1, sizeof(sent_data1));
    63  
    64    auto pair1 =
    65        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
    66  
    67    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair1->second_fd(),
    68                                         sent_data1, sizeof(sent_data1)));
    69  
    70    char sent_data2[20];
    71    RandomizeBuffer(sent_data2, sizeof(sent_data2));
    72  
    73    auto pair2 =
    74        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
    75  
    76    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair2->second_fd(),
    77                                         sent_data2, sizeof(sent_data2)));
    78  
    79    char received_data[sizeof(sent_data1) + sizeof(sent_data2)];
    80    ASSERT_THAT(
    81        ReadFd(sockets->second_fd(), received_data, sizeof(received_data)),
    82        SyscallSucceedsWithValue(sizeof(received_data)));
    83  
    84    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
    85    EXPECT_EQ(0, memcmp(sent_data2, received_data + sizeof(sent_data1),
    86                        sizeof(sent_data2)));
    87  }
    88  
    89  // ZeroLengthMessageFDDiscarded checks that control messages associated with
    90  // zero length messages are discarded.
    91  TEST_P(UnixStreamSocketPairTest, ZeroLengthMessageFDDiscarded) {
    92    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
    93  
    94    // Zero length arrays are invalid in ISO C++, so allocate one of size 1 and
    95    // send a length of 0.
    96    char sent_data1[1] = {};
    97  
    98    auto pair =
    99        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   100  
   101    ASSERT_NO_FATAL_FAILURE(
   102        SendSingleFD(sockets->first_fd(), pair->second_fd(), sent_data1, 0));
   103  
   104    char sent_data2[20];
   105    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   106  
   107    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   108                SyscallSucceedsWithValue(sizeof(sent_data2)));
   109  
   110    char received_data[sizeof(sent_data2)] = {};
   111  
   112    RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data));
   113    EXPECT_EQ(0, memcmp(sent_data2, received_data, sizeof(received_data)));
   114  }
   115  
   116  // FDPassCoalescedRecv checks that control messages not in the first message are
   117  // preserved in a coalesced recv.
   118  TEST_P(UnixStreamSocketPairTest, FDPassCoalescedRecv) {
   119    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   120  
   121    char sent_data[20];
   122    RandomizeBuffer(sent_data, sizeof(sent_data));
   123  
   124    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data, sizeof(sent_data) / 2),
   125                SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   126  
   127    auto pair =
   128        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   129  
   130    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   131                                         sent_data + sizeof(sent_data) / 2,
   132                                         sizeof(sent_data) / 2));
   133  
   134    char received_data[sizeof(sent_data)];
   135  
   136    int fd = -1;
   137    ASSERT_NO_FATAL_FAILURE(RecvSingleFD(sockets->second_fd(), &fd, received_data,
   138                                         sizeof(received_data)));
   139  
   140    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data)));
   141  
   142    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
   143  }
   144  
   145  // ReadsNotCoalescedAfterFDPass checks that messages after a message containing
   146  // an FD control message are not coalesced.
   147  TEST_P(UnixStreamSocketPairTest, ReadsNotCoalescedAfterFDPass) {
   148    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   149  
   150    char sent_data[20];
   151    RandomizeBuffer(sent_data, sizeof(sent_data));
   152  
   153    auto pair =
   154        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   155  
   156    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair->second_fd(),
   157                                         sent_data, sizeof(sent_data) / 2));
   158  
   159    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data + sizeof(sent_data) / 2,
   160                        sizeof(sent_data) / 2),
   161                SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   162  
   163    char received_data[sizeof(sent_data)];
   164  
   165    int fd = -1;
   166    ASSERT_NO_FATAL_FAILURE(RecvSingleFD(sockets->second_fd(), &fd, received_data,
   167                                         sizeof(received_data),
   168                                         sizeof(sent_data) / 2));
   169  
   170    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data) / 2));
   171  
   172    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair->first_fd()));
   173    EXPECT_THAT(close(fd), SyscallSucceeds());
   174  
   175    ASSERT_NO_FATAL_FAILURE(
   176        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(sent_data) / 2));
   177  
   178    EXPECT_EQ(0, memcmp(sent_data + sizeof(sent_data) / 2, received_data,
   179                        sizeof(sent_data) / 2));
   180  }
   181  
   182  // FDPassNotCombined checks that FD control messages are not combined in a
   183  // coalesced read.
   184  TEST_P(UnixStreamSocketPairTest, FDPassNotCombined) {
   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 pair1 =
   191        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   192  
   193    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair1->second_fd(),
   194                                         sent_data, sizeof(sent_data) / 2));
   195  
   196    auto pair2 =
   197        ASSERT_NO_ERRNO_AND_VALUE(UnixDomainSocketPair(SOCK_SEQPACKET).Create());
   198  
   199    ASSERT_NO_FATAL_FAILURE(SendSingleFD(sockets->first_fd(), pair2->second_fd(),
   200                                         sent_data + sizeof(sent_data) / 2,
   201                                         sizeof(sent_data) / 2));
   202  
   203    char received_data[sizeof(sent_data)];
   204  
   205    int fd = -1;
   206    ASSERT_NO_FATAL_FAILURE(RecvSingleFD(sockets->second_fd(), &fd, received_data,
   207                                         sizeof(received_data),
   208                                         sizeof(sent_data) / 2));
   209  
   210    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data) / 2));
   211  
   212    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair1->first_fd()));
   213  
   214    EXPECT_THAT(close(fd), SyscallSucceeds());
   215    fd = -1;
   216  
   217    ASSERT_NO_FATAL_FAILURE(RecvSingleFD(sockets->second_fd(), &fd, received_data,
   218                                         sizeof(received_data),
   219                                         sizeof(sent_data) / 2));
   220  
   221    EXPECT_EQ(0, memcmp(sent_data + sizeof(sent_data) / 2, received_data,
   222                        sizeof(sent_data) / 2));
   223  
   224    ASSERT_NO_FATAL_FAILURE(TransferTest(fd, pair2->first_fd()));
   225    EXPECT_THAT(close(fd), SyscallSucceeds());
   226  }
   227  
   228  TEST_P(UnixStreamSocketPairTest, CredPassPartialRead) {
   229    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   230  
   231    char sent_data[20];
   232    RandomizeBuffer(sent_data, sizeof(sent_data));
   233  
   234    struct ucred sent_creds;
   235  
   236    ASSERT_THAT(sent_creds.pid = getpid(), SyscallSucceeds());
   237    ASSERT_THAT(sent_creds.uid = getuid(), SyscallSucceeds());
   238    ASSERT_THAT(sent_creds.gid = getgid(), SyscallSucceeds());
   239  
   240    ASSERT_NO_FATAL_FAILURE(
   241        SendCreds(sockets->first_fd(), sent_creds, sent_data, sizeof(sent_data)));
   242  
   243    int one = 1;
   244    ASSERT_THAT(setsockopt(sockets->second_fd(), SOL_SOCKET, SO_PASSCRED, &one,
   245                           sizeof(one)),
   246                SyscallSucceeds());
   247  
   248    for (int i = 0; i < 2; i++) {
   249      char received_data[10];
   250      struct ucred received_creds;
   251      ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   252                                        received_data, sizeof(received_data),
   253                                        sizeof(received_data)));
   254  
   255      EXPECT_EQ(0, memcmp(sent_data + i * sizeof(received_data), received_data,
   256                          sizeof(received_data)));
   257      EXPECT_EQ(sent_creds.pid, received_creds.pid);
   258      EXPECT_EQ(sent_creds.uid, received_creds.uid);
   259      EXPECT_EQ(sent_creds.gid, received_creds.gid);
   260    }
   261  }
   262  
   263  // Unix stream sockets peek in the same way as datagram sockets.
   264  //
   265  // SinglePeek checks that only a single message is peekable in a single recv.
   266  TEST_P(UnixStreamSocketPairTest, SinglePeek) {
   267    if (!IsRunningOnGvisor()) {
   268      // Don't run this test on linux kernels newer than 4.3.x Linux kernel commit
   269      // 9f389e35674f5b086edd70ed524ca0f287259725 which changes this behavior. We
   270      // used to target 3.11 compatibility, so disable this test on newer kernels.
   271      //
   272      // NOTE(b/118902768): Bring this up to Linux 4.4 compatibility.
   273      auto version = ASSERT_NO_ERRNO_AND_VALUE(GetKernelVersion());
   274      SKIP_IF(version.major > 4 || (version.major == 4 && version.minor >= 3));
   275    }
   276  
   277    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   278    char sent_data[40];
   279    RandomizeBuffer(sent_data, sizeof(sent_data));
   280    ASSERT_THAT(RetryEINTR(send)(sockets->first_fd(), sent_data,
   281                                 sizeof(sent_data) / 2, 0),
   282                SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   283    ASSERT_THAT(
   284        RetryEINTR(send)(sockets->first_fd(), sent_data + sizeof(sent_data) / 2,
   285                         sizeof(sent_data) / 2, 0),
   286        SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   287    char received_data[sizeof(sent_data)];
   288    for (int i = 0; i < 3; i++) {
   289      memset(received_data, 0, sizeof(received_data));
   290      ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   291                                   sizeof(received_data), MSG_PEEK),
   292                  SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   293      EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data) / 2));
   294    }
   295    memset(received_data, 0, sizeof(received_data));
   296    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   297                                 sizeof(sent_data) / 2, 0),
   298                SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   299    EXPECT_EQ(0, memcmp(sent_data, received_data, sizeof(sent_data) / 2));
   300    memset(received_data, 0, sizeof(received_data));
   301    ASSERT_THAT(RetryEINTR(recv)(sockets->second_fd(), received_data,
   302                                 sizeof(sent_data) / 2, 0),
   303                SyscallSucceedsWithValue(sizeof(sent_data) / 2));
   304    EXPECT_EQ(0, memcmp(sent_data + sizeof(sent_data) / 2, received_data,
   305                        sizeof(sent_data) / 2));
   306  }
   307  
   308  TEST_P(UnixStreamSocketPairTest, CredsNotCoalescedUp) {
   309    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   310  
   311    char sent_data1[20];
   312    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   313  
   314    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   315                SyscallSucceedsWithValue(sizeof(sent_data1)));
   316  
   317    SetSoPassCred(sockets->second_fd());
   318  
   319    char sent_data2[20];
   320    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   321  
   322    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   323                SyscallSucceedsWithValue(sizeof(sent_data2)));
   324  
   325    char received_data[sizeof(sent_data1) + sizeof(sent_data2)];
   326  
   327    struct ucred received_creds;
   328    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   329                                      received_data, sizeof(received_data),
   330                                      sizeof(sent_data1)));
   331  
   332    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
   333  
   334    struct ucred want_creds {
   335      0, 65534, 65534
   336    };
   337  
   338    EXPECT_EQ(want_creds.pid, received_creds.pid);
   339    EXPECT_EQ(want_creds.uid, received_creds.uid);
   340    EXPECT_EQ(want_creds.gid, received_creds.gid);
   341  
   342    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   343                                      received_data, sizeof(received_data),
   344                                      sizeof(sent_data2)));
   345  
   346    EXPECT_EQ(0, memcmp(sent_data2, received_data, sizeof(sent_data2)));
   347  
   348    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   349    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   350    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   351  
   352    EXPECT_EQ(want_creds.pid, received_creds.pid);
   353    EXPECT_EQ(want_creds.uid, received_creds.uid);
   354    EXPECT_EQ(want_creds.gid, received_creds.gid);
   355  }
   356  
   357  TEST_P(UnixStreamSocketPairTest, CredsNotCoalescedDown) {
   358    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   359  
   360    SetSoPassCred(sockets->second_fd());
   361  
   362    char sent_data1[20];
   363    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   364  
   365    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   366                SyscallSucceedsWithValue(sizeof(sent_data1)));
   367  
   368    UnsetSoPassCred(sockets->second_fd());
   369  
   370    char sent_data2[20];
   371    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   372  
   373    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   374                SyscallSucceedsWithValue(sizeof(sent_data2)));
   375  
   376    SetSoPassCred(sockets->second_fd());
   377  
   378    char received_data[sizeof(sent_data1) + sizeof(sent_data2)];
   379    struct ucred received_creds;
   380  
   381    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   382                                      received_data, sizeof(received_data),
   383                                      sizeof(sent_data1)));
   384  
   385    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
   386  
   387    struct ucred want_creds;
   388    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   389    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   390    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   391  
   392    EXPECT_EQ(want_creds.pid, received_creds.pid);
   393    EXPECT_EQ(want_creds.uid, received_creds.uid);
   394    EXPECT_EQ(want_creds.gid, received_creds.gid);
   395  
   396    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   397                                      received_data, sizeof(received_data),
   398                                      sizeof(sent_data2)));
   399  
   400    EXPECT_EQ(0, memcmp(sent_data2, received_data, sizeof(sent_data2)));
   401  
   402    want_creds = {0, 65534, 65534};
   403  
   404    EXPECT_EQ(want_creds.pid, received_creds.pid);
   405    EXPECT_EQ(want_creds.uid, received_creds.uid);
   406    EXPECT_EQ(want_creds.gid, received_creds.gid);
   407  }
   408  
   409  TEST_P(UnixStreamSocketPairTest, CoalescedCredsNoPasscred) {
   410    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   411  
   412    SetSoPassCred(sockets->second_fd());
   413  
   414    char sent_data1[20];
   415    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   416  
   417    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   418                SyscallSucceedsWithValue(sizeof(sent_data1)));
   419  
   420    UnsetSoPassCred(sockets->second_fd());
   421  
   422    char sent_data2[20];
   423    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   424  
   425    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   426                SyscallSucceedsWithValue(sizeof(sent_data2)));
   427  
   428    char received_data[sizeof(sent_data1) + sizeof(sent_data2)];
   429  
   430    ASSERT_NO_FATAL_FAILURE(
   431        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   432  
   433    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
   434    EXPECT_EQ(0, memcmp(sent_data2, received_data + sizeof(sent_data1),
   435                        sizeof(sent_data2)));
   436  }
   437  
   438  TEST_P(UnixStreamSocketPairTest, CoalescedCreds1) {
   439    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   440  
   441    char sent_data1[20];
   442    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   443  
   444    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   445                SyscallSucceedsWithValue(sizeof(sent_data1)));
   446  
   447    char sent_data2[20];
   448    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   449  
   450    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   451                SyscallSucceedsWithValue(sizeof(sent_data2)));
   452  
   453    SetSoPassCred(sockets->second_fd());
   454  
   455    char received_data[sizeof(sent_data1) + sizeof(sent_data2)];
   456    struct ucred received_creds;
   457  
   458    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   459                                      received_data, sizeof(received_data)));
   460  
   461    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
   462    EXPECT_EQ(0, memcmp(sent_data2, received_data + sizeof(sent_data1),
   463                        sizeof(sent_data2)));
   464  
   465    struct ucred want_creds {
   466      0, 65534, 65534
   467    };
   468  
   469    EXPECT_EQ(want_creds.pid, received_creds.pid);
   470    EXPECT_EQ(want_creds.uid, received_creds.uid);
   471    EXPECT_EQ(want_creds.gid, received_creds.gid);
   472  }
   473  
   474  TEST_P(UnixStreamSocketPairTest, CoalescedCreds2) {
   475    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   476  
   477    SetSoPassCred(sockets->second_fd());
   478  
   479    char sent_data1[20];
   480    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   481  
   482    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   483                SyscallSucceedsWithValue(sizeof(sent_data1)));
   484  
   485    char sent_data2[20];
   486    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   487  
   488    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   489                SyscallSucceedsWithValue(sizeof(sent_data2)));
   490  
   491    char received_data[sizeof(sent_data1) + sizeof(sent_data2)];
   492    struct ucred received_creds;
   493  
   494    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds,
   495                                      received_data, sizeof(received_data)));
   496  
   497    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
   498    EXPECT_EQ(0, memcmp(sent_data2, received_data + sizeof(sent_data1),
   499                        sizeof(sent_data2)));
   500  
   501    struct ucred want_creds;
   502    ASSERT_THAT(want_creds.pid = getpid(), SyscallSucceeds());
   503    ASSERT_THAT(want_creds.uid = getuid(), SyscallSucceeds());
   504    ASSERT_THAT(want_creds.gid = getgid(), SyscallSucceeds());
   505  
   506    EXPECT_EQ(want_creds.pid, received_creds.pid);
   507    EXPECT_EQ(want_creds.uid, received_creds.uid);
   508    EXPECT_EQ(want_creds.gid, received_creds.gid);
   509  }
   510  
   511  TEST_P(UnixStreamSocketPairTest, NonCoalescedDifferingCreds1) {
   512    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   513  
   514    char sent_data1[20];
   515    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   516  
   517    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   518                SyscallSucceedsWithValue(sizeof(sent_data1)));
   519  
   520    SetSoPassCred(sockets->second_fd());
   521  
   522    char sent_data2[20];
   523    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   524  
   525    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   526                SyscallSucceedsWithValue(sizeof(sent_data2)));
   527  
   528    char received_data1[sizeof(sent_data1) + sizeof(sent_data2)];
   529    struct ucred received_creds1;
   530  
   531    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds1,
   532                                      received_data1, sizeof(sent_data1)));
   533  
   534    EXPECT_EQ(0, memcmp(sent_data1, received_data1, sizeof(sent_data1)));
   535  
   536    struct ucred want_creds1 {
   537      0, 65534, 65534
   538    };
   539  
   540    EXPECT_EQ(want_creds1.pid, received_creds1.pid);
   541    EXPECT_EQ(want_creds1.uid, received_creds1.uid);
   542    EXPECT_EQ(want_creds1.gid, received_creds1.gid);
   543  
   544    char received_data2[sizeof(sent_data1) + sizeof(sent_data2)];
   545    struct ucred received_creds2;
   546  
   547    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds2,
   548                                      received_data2, sizeof(sent_data2)));
   549  
   550    EXPECT_EQ(0, memcmp(sent_data2, received_data2, sizeof(sent_data2)));
   551  
   552    struct ucred want_creds2;
   553    ASSERT_THAT(want_creds2.pid = getpid(), SyscallSucceeds());
   554    ASSERT_THAT(want_creds2.uid = getuid(), SyscallSucceeds());
   555    ASSERT_THAT(want_creds2.gid = getgid(), SyscallSucceeds());
   556  
   557    EXPECT_EQ(want_creds2.pid, received_creds2.pid);
   558    EXPECT_EQ(want_creds2.uid, received_creds2.uid);
   559    EXPECT_EQ(want_creds2.gid, received_creds2.gid);
   560  }
   561  
   562  TEST_P(UnixStreamSocketPairTest, NonCoalescedDifferingCreds2) {
   563    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   564  
   565    SetSoPassCred(sockets->second_fd());
   566  
   567    char sent_data1[20];
   568    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   569  
   570    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   571                SyscallSucceedsWithValue(sizeof(sent_data1)));
   572  
   573    UnsetSoPassCred(sockets->second_fd());
   574  
   575    char sent_data2[20];
   576    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   577  
   578    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   579                SyscallSucceedsWithValue(sizeof(sent_data2)));
   580  
   581    SetSoPassCred(sockets->second_fd());
   582  
   583    char received_data1[sizeof(sent_data1) + sizeof(sent_data2)];
   584    struct ucred received_creds1;
   585  
   586    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds1,
   587                                      received_data1, sizeof(sent_data1)));
   588  
   589    EXPECT_EQ(0, memcmp(sent_data1, received_data1, sizeof(sent_data1)));
   590  
   591    struct ucred want_creds1;
   592    ASSERT_THAT(want_creds1.pid = getpid(), SyscallSucceeds());
   593    ASSERT_THAT(want_creds1.uid = getuid(), SyscallSucceeds());
   594    ASSERT_THAT(want_creds1.gid = getgid(), SyscallSucceeds());
   595  
   596    EXPECT_EQ(want_creds1.pid, received_creds1.pid);
   597    EXPECT_EQ(want_creds1.uid, received_creds1.uid);
   598    EXPECT_EQ(want_creds1.gid, received_creds1.gid);
   599  
   600    char received_data2[sizeof(sent_data1) + sizeof(sent_data2)];
   601    struct ucred received_creds2;
   602  
   603    ASSERT_NO_FATAL_FAILURE(RecvCreds(sockets->second_fd(), &received_creds2,
   604                                      received_data2, sizeof(sent_data2)));
   605  
   606    EXPECT_EQ(0, memcmp(sent_data2, received_data2, sizeof(sent_data2)));
   607  
   608    struct ucred want_creds2 {
   609      0, 65534, 65534
   610    };
   611  
   612    EXPECT_EQ(want_creds2.pid, received_creds2.pid);
   613    EXPECT_EQ(want_creds2.uid, received_creds2.uid);
   614    EXPECT_EQ(want_creds2.gid, received_creds2.gid);
   615  }
   616  
   617  TEST_P(UnixStreamSocketPairTest, CoalescedDifferingCreds) {
   618    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   619  
   620    SetSoPassCred(sockets->second_fd());
   621  
   622    char sent_data1[20];
   623    RandomizeBuffer(sent_data1, sizeof(sent_data1));
   624  
   625    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data1, sizeof(sent_data1)),
   626                SyscallSucceedsWithValue(sizeof(sent_data1)));
   627  
   628    char sent_data2[20];
   629    RandomizeBuffer(sent_data2, sizeof(sent_data2));
   630  
   631    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data2, sizeof(sent_data2)),
   632                SyscallSucceedsWithValue(sizeof(sent_data2)));
   633  
   634    UnsetSoPassCred(sockets->second_fd());
   635  
   636    char sent_data3[20];
   637    RandomizeBuffer(sent_data3, sizeof(sent_data3));
   638  
   639    ASSERT_THAT(WriteFd(sockets->first_fd(), sent_data3, sizeof(sent_data3)),
   640                SyscallSucceedsWithValue(sizeof(sent_data3)));
   641  
   642    char received_data[sizeof(sent_data1) + sizeof(sent_data2) +
   643                       sizeof(sent_data3)];
   644  
   645    ASSERT_NO_FATAL_FAILURE(
   646        RecvNoCmsg(sockets->second_fd(), received_data, sizeof(received_data)));
   647  
   648    EXPECT_EQ(0, memcmp(sent_data1, received_data, sizeof(sent_data1)));
   649    EXPECT_EQ(0, memcmp(sent_data2, received_data + sizeof(sent_data1),
   650                        sizeof(sent_data2)));
   651    EXPECT_EQ(0, memcmp(sent_data3,
   652                        received_data + sizeof(sent_data1) + sizeof(sent_data2),
   653                        sizeof(sent_data3)));
   654  }
   655  
   656  INSTANTIATE_TEST_SUITE_P(
   657      AllUnixDomainSockets, UnixStreamSocketPairTest,
   658      ::testing::ValuesIn(IncludeReversals(VecCat<SocketPairKind>(
   659          ApplyVec<SocketPairKind>(UnixDomainSocketPair,
   660                                   AllBitwiseCombinations(List<int>{SOCK_STREAM},
   661                                                          List<int>{
   662                                                              0, SOCK_NONBLOCK})),
   663          ApplyVec<SocketPairKind>(FilesystemBoundUnixDomainSocketPair,
   664                                   AllBitwiseCombinations(List<int>{SOCK_STREAM},
   665                                                          List<int>{
   666                                                              0, SOCK_NONBLOCK})),
   667          ApplyVec<SocketPairKind>(
   668              AbstractBoundUnixDomainSocketPair,
   669              AllBitwiseCombinations(List<int>{SOCK_STREAM},
   670                                     List<int>{0, SOCK_NONBLOCK}))))));
   671  
   672  // Test fixture for tests that apply to pairs of unbound unix stream sockets.
   673  using UnboundUnixStreamSocketPairTest = SocketPairTest;
   674  
   675  TEST_P(UnboundUnixStreamSocketPairTest, SendtoWithoutConnect) {
   676    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   677  
   678    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
   679                     sockets->first_addr_size()),
   680                SyscallSucceeds());
   681  
   682    char data = 'a';
   683    ASSERT_THAT(sendto(sockets->second_fd(), &data, sizeof(data), 0,
   684                       sockets->first_addr(), sockets->first_addr_size()),
   685                SyscallFailsWithErrno(EOPNOTSUPP));
   686  }
   687  
   688  TEST_P(UnboundUnixStreamSocketPairTest, SendtoWithoutConnectIgnoresAddr) {
   689    // FIXME(b/68223466): gVisor tries to find /foo/bar and thus returns ENOENT.
   690    if (IsRunningOnGvisor()) {
   691      return;
   692    }
   693  
   694    auto sockets = ASSERT_NO_ERRNO_AND_VALUE(NewSocketPair());
   695  
   696    ASSERT_THAT(bind(sockets->first_fd(), sockets->first_addr(),
   697                     sockets->first_addr_size()),
   698                SyscallSucceeds());
   699  
   700    // Even a bogus address is completely ignored.
   701    constexpr char kPath[] = "/foo/bar";
   702  
   703    // Sanity check that kPath doesn't exist.
   704    struct stat s;
   705    ASSERT_THAT(stat(kPath, &s), SyscallFailsWithErrno(ENOENT));
   706  
   707    struct sockaddr_un addr = {};
   708    addr.sun_family = AF_UNIX;
   709    memcpy(addr.sun_path, kPath, sizeof(kPath));
   710  
   711    char data = 'a';
   712    ASSERT_THAT(
   713        sendto(sockets->second_fd(), &data, sizeof(data), 0,
   714               reinterpret_cast<const struct sockaddr*>(&addr), sizeof(addr)),
   715        SyscallFailsWithErrno(EOPNOTSUPP));
   716  }
   717  
   718  INSTANTIATE_TEST_SUITE_P(
   719      AllUnixDomainSockets, UnboundUnixStreamSocketPairTest,
   720      ::testing::ValuesIn(IncludeReversals(VecCat<SocketPairKind>(
   721          ApplyVec<SocketPairKind>(FilesystemUnboundUnixDomainSocketPair,
   722                                   AllBitwiseCombinations(List<int>{SOCK_STREAM},
   723                                                          List<int>{
   724                                                              0, SOCK_NONBLOCK})),
   725          ApplyVec<SocketPairKind>(
   726              AbstractUnboundUnixDomainSocketPair,
   727              AllBitwiseCombinations(List<int>{SOCK_STREAM},
   728                                     List<int>{0, SOCK_NONBLOCK}))))));
   729  
   730  }  // namespace
   731  
   732  }  // namespace testing
   733  }  // namespace gvisor