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