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