gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/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/unix_domain_socket_test_util.h" 20 #include "test/util/socket_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