1 /* 2 * Test Program for Unix Domain Sockets 3 * 4 * Overview: This program tests Unix Domain Sockets. It attempts 5 * to exercise the functions associated with Unix Domain Sockets. 6 * It also attempts to make sure all of the functions which handle 7 * file/socket descriptors work correctly when given a socket 8 * descriptor for a Unix domain socket. It also implicitly checks 9 * for the existance of constants like AF_UNIX and structures like 10 * sockaddr_un (it won't compile if they aren't defined). Besides 11 * checking that the sockets work properly, this test program also 12 * checks that the errors returned conform to the POSIX 2008 13 * standards. Some tests are omitted as they could adversely affect 14 * the operation of the host system. For example, implementing a test 15 * for socket() failing with errno = ENFILE would require using up all 16 * of the file descriptors supported by the OS (defined in 17 * /proc/sys/fs/file-max on Linux); this could cause problems for 18 * daemons and other processes running on the system. Some tests are 19 * omitted because they would require changes to libc or the kernel. 20 * For example, getting EINTR would require delaying the system call 21 * execution time long enough to raise a signal to interupt it. Some 22 * tests were omitted because the particular errors cannot occur when 23 * using Unix domain sockets. For example, write() will never fail with 24 * ENETDOWN because Unix domain sockets don't use network interfaces. 25 * 26 * Structure: Some functions can be tested or partially tested without 27 * making a connection, socket() for example. These have test 28 * functions like test_NAME(). The functionality that needs two way 29 * communication is contained within test_xfer(). 30 * 31 * Functions Tested: accept(), bind(), close(), connect(), dup(), 32 * dup2(), fstat(), getpeername(), getsockname(), getsockopt(), 33 * listen(), read(), readv(), recv(), recvfrom(), recvmsg(), select(), 34 * send(), sendmsg(), sendto(), setsockopt(), shutdown(), socket(), 35 * socketpair(), write(), writev() 36 */ 37 38 #include <ctype.h> 39 #include <errno.h> 40 #include <fcntl.h> 41 #include <signal.h> 42 #include <stdio.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <sys/socket.h> 46 #include <sys/ucred.h> 47 #include <sys/stat.h> 48 #include <sys/time.h> 49 #include <sys/types.h> 50 #include <sys/uio.h> 51 #include <sys/un.h> 52 #include <sys/wait.h> 53 #include <time.h> 54 #include <unistd.h> 55 56 /* Maximum number of errors that we'll allow to occur before this test 57 * program gives us and quits. 58 */ 59 int max_error = 4; 60 #include "common.h" 61 #include "common-socket.h" 62 63 64 /* Use the common testing code instead of reinventing the wheel. */ 65 66 /* path of the unix domain socket */ 67 #define TEST_SUN_PATH "test.sock" 68 #define TEST_SUN_PATHB "testb.sock" 69 70 /* filenames for symlinks -- we link these to each other to test ELOOP .*/ 71 #define TEST_SYM_A "test.a" 72 #define TEST_SYM_B "test.b" 73 74 /* text file and test phrase for testing file descriptor passing */ 75 #define TEST_TXT_FILE "test.txt" 76 #define MSG "This raccoon loves to eat bugs.\n" 77 78 /* socket types supported */ 79 static int types[3] = {SOCK_STREAM, SOCK_SEQPACKET, SOCK_DGRAM}; 80 static char sock_fullpath[PATH_MAX + 1]; 81 82 /* Convert name to the full path of the socket. Assumes name is in cwd. */ 83 static char *fullpath(const char *name) 84 { 85 char cwd[PATH_MAX + 1]; 86 87 if (realpath(".", cwd) == NULL) 88 test_fail("Couldn't retrieve current working dir"); 89 90 snprintf(sock_fullpath, PATH_MAX, "%s/%s", cwd, name); 91 92 return(sock_fullpath); 93 } 94 95 static void test_header(void) 96 { 97 struct sockaddr_un sun; 98 debug("entering test_header()"); 99 100 sun.sun_family = AF_UNIX; 101 sun.sun_path[0] = 'x'; 102 sun.sun_path[1] = 'x'; 103 sun.sun_path[2] = 'x'; 104 sun.sun_path[3] = '\0'; 105 106 if (SUN_LEN(&sun) != 5) { 107 test_fail("SUN_LEN(&sun) should be 5"); 108 } 109 110 if (PF_UNIX != PF_LOCAL || PF_UNIX != AF_UNIX) { 111 test_fail("PF_UNIX, PF_LOCAL and AF_UNIX"); 112 } 113 } 114 115 static void test_socketpair(void) 116 { 117 char buf[128]; 118 struct sockaddr_un addr; 119 int socket_vector[2]; 120 int rc; 121 int i; 122 123 debug("entering test_socketpair()"); 124 125 UNLINK(TEST_SUN_PATH); 126 memset(&addr, '\0', sizeof(struct sockaddr_un)); 127 addr.sun_family = AF_UNIX; 128 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 129 130 debug("Testing socketpair() success"); 131 132 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector); 133 if (rc == -1) { 134 test_fail("socketpair() should have worked"); 135 } 136 137 debug("Testing a simple read/write using sockets from socketpair()"); 138 memset(buf, '\0', sizeof(buf)); 139 140 strncpy(buf, "Howdy Partner", sizeof(buf) - 1); 141 142 rc = write(socket_vector[0], buf, sizeof(buf)); 143 if (rc == -1) { 144 test_fail("write(sd, buf, sizeof(buf)) failed unexpectedly"); 145 } 146 147 memset(buf, '\0', sizeof(buf)); 148 149 rc = read(socket_vector[1], buf, sizeof(buf)); 150 if (rc == -1) { 151 test_fail("read() failed unexpectedly"); 152 } 153 154 if (strncmp(buf, "Howdy Partner", strlen("Howdy Partner")) != 0) { 155 test_fail("We did not read what we wrote"); 156 } 157 158 CLOSE(socket_vector[0]); 159 CLOSE(socket_vector[1]); 160 161 debug("Test socketpair() with all FDs open by this process"); 162 163 for (i = 3; i < getdtablesize(); i++) { 164 rc = open("/dev/null", O_RDONLY); 165 if (rc == -1) { 166 test_fail("we couldn't open /dev/null for read"); 167 } 168 } 169 170 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, socket_vector); 171 if (!(rc == -1 && errno == EMFILE)) { 172 test_fail("socketpair() should have failed with EMFILE"); 173 } 174 175 for (i = 3; i < getdtablesize(); i++) { 176 CLOSE(i); 177 } 178 179 rc = socketpair(PF_UNIX, SOCK_STREAM, 4, socket_vector); 180 if (!(rc == -1 && errno == EPROTONOSUPPORT)) { 181 test_fail("socketpair() should have failed"); 182 } 183 184 debug("leaving test_socketpair()"); 185 } 186 187 static void test_ucred(void) 188 { 189 struct uucred credentials; 190 socklen_t ucred_length; 191 uid_t euid = geteuid(); 192 gid_t egid = getegid(); 193 int sv[2]; 194 int rc; 195 196 debug("Test credentials passing"); 197 198 ucred_length = sizeof(struct uucred); 199 200 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sv); 201 if (rc == -1) { 202 test_fail("socketpair(PF_UNIX, SOCK_STREAM, 0, sv) failed"); 203 } 204 205 memset(&credentials, '\0', ucred_length); 206 rc = getsockopt(sv[0], SOL_SOCKET, SO_PEERCRED, &credentials, 207 &ucred_length); 208 if (rc == -1) { 209 test_fail("getsockopt(SO_PEERCRED) failed"); 210 } else if (credentials.cr_ngroups != 0 || 211 credentials.cr_uid != geteuid() || 212 credentials.cr_gid != getegid()) { 213 /* printf("%d=%d %d=%d %d=%d",credentials.cr_ngroups, 0, 214 credentials.cr_uid, geteuid(), credentials.cr_gid, getegid()); */ 215 test_fail("Credential passing gave us the wrong cred"); 216 } 217 218 rc = getpeereid(sv[0], &euid, &egid); 219 if (rc == -1) { 220 test_fail("getpeereid(sv[0], &euid, &egid) failed"); 221 } else if (credentials.cr_uid != euid || credentials.cr_gid != egid) { 222 test_fail("getpeereid() didn't give the correct euid/egid"); 223 } 224 225 CLOSE(sv[0]); 226 CLOSE(sv[1]); 227 } 228 229 static void callback_check_sockaddr(const struct sockaddr *sockaddr, 230 socklen_t sockaddrlen, const char *callname, int addridx) { 231 char buf[256]; 232 const char *path; 233 const struct sockaddr_un *sockaddr_un = 234 (const struct sockaddr_un *) sockaddr; 235 236 switch (addridx) { 237 case 1: path = TEST_SUN_PATH; break; 238 case 2: path = TEST_SUN_PATHB; break; 239 default: 240 fprintf(stderr, "error: invalid addridx %d in " 241 "callback_check_sockaddr\n", addridx); 242 abort(); 243 } 244 245 if (!(sockaddr_un->sun_family == AF_UNIX && 246 strncmp(sockaddr_un->sun_path, 247 fullpath(path), 248 sizeof(sockaddr_un->sun_path) - 1) == 0)) { 249 250 snprintf(buf, sizeof(buf), "%s() didn't return the right addr", 251 callname); 252 test_fail(buf); 253 fprintf(stderr, "exp: '%s' | got: '%s'\n", path, 254 sockaddr_un->sun_path); 255 } 256 } 257 258 static void callback_cleanup(void) { 259 UNLINK(TEST_SUN_PATH); 260 UNLINK(TEST_SUN_PATHB); 261 UNLINK(TEST_SYM_A); 262 UNLINK(TEST_SYM_B); 263 } 264 265 static void test_bind_unix(void) 266 { 267 struct sockaddr_un addr; 268 int sd; 269 int rc; 270 271 debug("entering test_bind_unix()"); 272 UNLINK(TEST_SUN_PATH); 273 memset(&addr, '\0', sizeof(struct sockaddr_un)); 274 addr.sun_family = AF_UNIX; 275 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 276 277 debug("Test bind() with an empty sun_path"); 278 279 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 280 memset(addr.sun_path, '\0', sizeof(addr.sun_path)); 281 errno = 0; 282 283 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 284 if (!(rc == -1 && errno == ENOENT)) { 285 test_fail("bind() should have failed with ENOENT"); 286 } 287 CLOSE(sd); 288 289 debug("Test bind() using a symlink loop"); 290 291 UNLINK(TEST_SUN_PATH); 292 UNLINK(TEST_SYM_A); 293 UNLINK(TEST_SYM_B); 294 295 SYMLINK(TEST_SYM_A, TEST_SYM_B); 296 SYMLINK(TEST_SYM_B, TEST_SYM_A); 297 298 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 299 300 strncpy(addr.sun_path, TEST_SYM_A, sizeof(addr.sun_path) - 1); 301 errno = 0; 302 rc = bind(sd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)); 303 if (!((rc == -1) && (errno == ELOOP))) { 304 test_fail("bind() should have failed with ELOOP"); 305 } 306 CLOSE(sd); 307 308 UNLINK(TEST_SUN_PATH); 309 UNLINK(TEST_SYM_A); 310 UNLINK(TEST_SYM_B); 311 312 /* Test bind with garbage in sockaddr_un */ 313 memset(&addr, '?', sizeof(struct sockaddr_un)); 314 addr.sun_family = AF_UNIX; 315 addr.sun_path[0] = 'f'; 316 addr.sun_path[1] = 'o'; 317 addr.sun_path[2] = 'o'; 318 addr.sun_path[3] = '\0'; 319 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 320 rc = bind(sd, (struct sockaddr *) &addr, strlen(addr.sun_path) + 1); 321 if (rc == -1) { 322 test_fail("bind() should have worked"); 323 } 324 CLOSE(sd); 325 UNLINK("foo"); 326 327 debug("leaving test_bind_unix()"); 328 } 329 330 static void callback_xfer_prepclient(void) { 331 debug("Creating symlink to TEST_SUN_PATH"); 332 333 SYMLINK(TEST_SUN_PATH, TEST_SYM_A); 334 } 335 336 static void callback_xfer_peercred(int sd) { 337 struct uucred credentials; 338 int rc; 339 socklen_t ucred_length; 340 341 ucred_length = sizeof(struct uucred); 342 343 debug("Test passing the client credentials to the server"); 344 345 memset(&credentials, '\0', ucred_length); 346 rc = getsockopt(sd, SOL_SOCKET, SO_PEERCRED, &credentials, 347 &ucred_length); 348 349 if (rc == -1) { 350 test_fail("[client] getsockopt() failed"); 351 } else if (credentials.cr_uid != geteuid() || 352 credentials.cr_gid != getegid()) { 353 printf("%d=%d=%d %d=%d=%d\n", credentials.cr_uid, getuid(), 354 geteuid(), credentials.cr_gid, getgid(), getegid()); 355 test_fail("[client] Credential passing gave us a bad UID/GID"); 356 } 357 } 358 359 static void test_vectorio(int type) 360 { 361 int sv[2]; 362 int rc; 363 struct iovec iov[3]; 364 char buf1[BUFSIZE]; 365 char buf2[BUFSIZE]; 366 char buf3[BUFSIZE]; 367 char buf4[BUFSIZE*3]; 368 const struct iovec *iovp = iov; 369 370 debug("begin vectorio tests"); 371 372 memset(buf1, '\0', BUFSIZE); 373 strncpy(buf1, "HELLO ", BUFSIZE - 1); 374 375 memset(buf2, '\0', BUFSIZE); 376 strncpy(buf2, "WORLD", BUFSIZE - 1); 377 378 memset(buf3, '\0', BUFSIZE); 379 380 rc = socketpair(PF_UNIX, type, 0, sv); 381 if (rc == -1) { 382 test_fail("socketpair"); 383 } 384 385 iov[0].iov_base = buf1; 386 iov[0].iov_len = strlen(buf1); 387 iov[1].iov_base = buf2; 388 iov[1].iov_len = strlen(buf2); 389 iov[2].iov_base = buf3; 390 iov[2].iov_len = 1; 391 392 rc = writev(sv[0], iovp, 3); 393 if (rc == -1) { 394 test_fail("writev"); 395 } 396 397 memset(buf4, '\0', BUFSIZE*3); 398 399 rc = read(sv[1], buf4, BUFSIZE*3); 400 if (rc == -1) { 401 test_fail("read"); 402 } 403 404 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) { 405 test_fail("the string we read was not 'HELLO WORLD'"); 406 } 407 408 memset(buf1, '\0', BUFSIZE); 409 strncpy(buf1, "Unit Test Time", BUFSIZE - 1); 410 411 rc = write(sv[1], buf1, strlen(buf1) + 1); 412 if (rc == -1) { 413 test_fail("write"); 414 } 415 416 memset(buf2, '\0', BUFSIZE); 417 memset(buf3, '\0', BUFSIZE); 418 memset(buf4, '\0', BUFSIZE*3); 419 420 iov[0].iov_base = buf2; 421 iov[0].iov_len = 5; 422 iov[1].iov_base = buf3; 423 iov[1].iov_len = 5; 424 iov[2].iov_base = buf4; 425 iov[2].iov_len = 32; 426 427 rc = readv(sv[0], iovp, 3); 428 if (rc == -1) { 429 test_fail("readv"); 430 } 431 432 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) || 433 strncmp(buf4, "Time", 4)) { 434 test_fail("readv"); 435 } 436 437 rc = close(sv[0]); 438 if (rc == -1) { 439 test_fail("close"); 440 } 441 442 rc = close(sv[1]); 443 if (rc == -1) { 444 test_fail("close"); 445 } 446 447 debug("done vector io tests"); 448 } 449 450 static void test_msg(int type) 451 { 452 int sv[2]; 453 int rc; 454 struct msghdr msg1; 455 struct msghdr msg2; 456 struct iovec iov[3]; 457 char buf1[BUFSIZE]; 458 char buf2[BUFSIZE]; 459 char buf3[BUFSIZE]; 460 char buf4[BUFSIZE*3]; 461 462 debug("begin sendmsg/recvmsg tests"); 463 464 memset(buf1, '\0', BUFSIZE); 465 strncpy(buf1, "HELLO ", BUFSIZE - 1); 466 467 memset(buf2, '\0', BUFSIZE); 468 strncpy(buf2, "WORLD", BUFSIZE - 1); 469 470 memset(buf3, '\0', BUFSIZE); 471 472 rc = socketpair(PF_UNIX, type, 0, sv); 473 if (rc == -1) { 474 test_fail("socketpair"); 475 } 476 477 iov[0].iov_base = buf1; 478 iov[0].iov_len = strlen(buf1); 479 iov[1].iov_base = buf2; 480 iov[1].iov_len = strlen(buf2); 481 iov[2].iov_base = buf3; 482 iov[2].iov_len = 1; 483 484 memset(&msg1, '\0', sizeof(struct msghdr)); 485 msg1.msg_name = NULL; 486 msg1.msg_namelen = 0; 487 msg1.msg_iov = iov; 488 msg1.msg_iovlen = 3; 489 msg1.msg_control = NULL; 490 msg1.msg_controllen = 0; 491 msg1.msg_flags = 0; 492 493 rc = sendmsg(sv[0], &msg1, 0); 494 if (rc == -1) { 495 test_fail("writev"); 496 } 497 498 memset(buf4, '\0', BUFSIZE*3); 499 500 rc = read(sv[1], buf4, BUFSIZE*3); 501 if (rc == -1) { 502 test_fail("read"); 503 } 504 505 if (strncmp(buf4, "HELLO WORLD", strlen("HELLO WORLD"))) { 506 test_fail("the string we read was not 'HELLO WORLD'"); 507 } 508 509 memset(buf1, '\0', BUFSIZE); 510 strncpy(buf1, "Unit Test Time", BUFSIZE - 1); 511 512 rc = write(sv[1], buf1, strlen(buf1) + 1); 513 if (rc == -1) { 514 test_fail("write"); 515 } 516 517 memset(buf2, '\0', BUFSIZE); 518 memset(buf3, '\0', BUFSIZE); 519 memset(buf4, '\0', BUFSIZE*3); 520 521 iov[0].iov_base = buf2; 522 iov[0].iov_len = 5; 523 iov[1].iov_base = buf3; 524 iov[1].iov_len = 5; 525 iov[2].iov_base = buf4; 526 iov[2].iov_len = 32; 527 528 memset(&msg2, '\0', sizeof(struct msghdr)); 529 msg2.msg_name = NULL; 530 msg2.msg_namelen = 0; 531 msg2.msg_iov = iov; 532 msg2.msg_iovlen = 3; 533 msg2.msg_control = NULL; 534 msg2.msg_controllen = 0; 535 msg2.msg_flags = 0; 536 537 rc = recvmsg(sv[0], &msg2, 0); 538 if (rc == -1) { 539 test_fail("readv"); 540 } 541 542 if (strncmp(buf2, "Unit ", 5) || strncmp(buf3, "Test ", 5) || 543 strncmp(buf4, "Time", 4)) { 544 test_fail("readv"); 545 } 546 547 rc = close(sv[0]); 548 if (rc == -1) { 549 test_fail("close"); 550 } 551 552 rc = close(sv[1]); 553 if (rc == -1) { 554 test_fail("close"); 555 } 556 } 557 558 static void test_scm_credentials(void) 559 { 560 int rc; 561 int src; 562 int dst; 563 struct uucred cred; 564 struct cmsghdr *cmsg = NULL; 565 struct sockaddr_un addr; 566 struct iovec iov[3]; 567 struct msghdr msg1; 568 struct msghdr msg2; 569 char buf1[BUFSIZE]; 570 char buf2[BUFSIZE]; 571 char buf3[BUFSIZE]; 572 char ctrl[BUFSIZE]; 573 socklen_t addrlen = sizeof(struct sockaddr_un); 574 575 debug("test_scm_credentials"); 576 577 UNLINK(TEST_SUN_PATH); 578 UNLINK(TEST_SUN_PATHB); 579 580 debug("creating src socket"); 581 582 src = socket(PF_UNIX, SOCK_DGRAM, 0); 583 if (src == -1) { 584 test_fail("socket"); 585 } 586 587 debug("creating dst socket"); 588 589 dst = socket(PF_UNIX, SOCK_DGRAM, 0); 590 if (dst == -1) { 591 test_fail("socket"); 592 } 593 594 debug("binding src socket"); 595 596 memset(&addr, '\0', sizeof(struct sockaddr_un)); 597 addr.sun_family = AF_UNIX; 598 strncpy(addr.sun_path, TEST_SUN_PATHB, sizeof(addr.sun_path) - 1); 599 rc = bind(src, (struct sockaddr *) &addr, addrlen); 600 if (rc == -1) { 601 test_fail("bind"); 602 } 603 604 debug("binding dst socket"); 605 606 memset(&addr, '\0', sizeof(struct sockaddr_un)); 607 addr.sun_family = AF_UNIX; 608 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 609 610 rc = bind(dst, (struct sockaddr *) &addr, addrlen); 611 if (rc == -1) { 612 test_fail("bind"); 613 } 614 615 memset(&buf1, '\0', BUFSIZE); 616 memset(&buf2, '\0', BUFSIZE); 617 memset(&buf3, '\0', BUFSIZE); 618 memset(&ctrl, '\0', BUFSIZE); 619 620 strncpy(buf1, "Minix ", BUFSIZE-1); 621 strncpy(buf2, "is ", BUFSIZE-1); 622 strncpy(buf3, "great!", BUFSIZE-1); 623 624 iov[0].iov_base = buf1; 625 iov[0].iov_len = 6; 626 iov[1].iov_base = buf2; 627 iov[1].iov_len = 3; 628 iov[2].iov_base = buf3; 629 iov[2].iov_len = 32; 630 631 memset(&msg1, '\0', sizeof(struct msghdr)); 632 msg1.msg_name = &addr; 633 msg1.msg_namelen = addrlen; 634 msg1.msg_iov = iov; 635 msg1.msg_iovlen = 3; 636 msg1.msg_control = NULL; 637 msg1.msg_controllen = 0; 638 msg1.msg_flags = 0; 639 640 debug("sending msg1"); 641 642 rc = sendmsg(src, &msg1, 0); 643 if (rc == -1) { 644 test_fail("sendmsg"); 645 } 646 647 memset(&buf1, '\0', BUFSIZE); 648 memset(&buf2, '\0', BUFSIZE); 649 memset(&buf3, '\0', BUFSIZE); 650 memset(&ctrl, '\0', BUFSIZE); 651 652 iov[0].iov_base = buf1; 653 iov[0].iov_len = 9; 654 iov[1].iov_base = buf2; 655 iov[1].iov_len = 32; 656 657 memset(&addr, '\0', sizeof(struct sockaddr_un)); 658 memset(&msg2, '\0', sizeof(struct msghdr)); 659 msg2.msg_name = &addr; 660 msg2.msg_namelen = sizeof(struct sockaddr_un); 661 msg2.msg_iov = iov; 662 msg2.msg_iovlen = 2; 663 msg2.msg_control = ctrl; 664 msg2.msg_controllen = BUFSIZE; 665 msg2.msg_flags = 0; 666 667 debug("recv msg2"); 668 669 rc = recvmsg(dst, &msg2, 0); 670 if (rc == -1) { 671 test_fail("recvmsg"); 672 } 673 674 debug("checking results"); 675 676 if (strncmp(buf1, "Minix is ", 9) || strncmp(buf2, "great!", 6)) { 677 test_fail("recvmsg"); 678 } 679 680 /* we need to use the full path "/usr/src/test/DIR_56/testb.sock" 681 * because that is what is returned by recvmsg(). 682 */ 683 if (addr.sun_family != AF_UNIX || strcmp(addr.sun_path, 684 fullpath(TEST_SUN_PATHB))) { 685 test_fail("recvmsg"); 686 } 687 688 debug("looking for credentials"); 689 690 memset(&cred, '\0', sizeof(struct uucred)); 691 for (cmsg = CMSG_FIRSTHDR(&msg2); cmsg != NULL; 692 cmsg = CMSG_NXTHDR(&msg2, cmsg)) { 693 694 if (cmsg->cmsg_level == SOL_SOCKET && 695 cmsg->cmsg_type == SCM_CREDS) { 696 697 memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct uucred)); 698 break; 699 } 700 } 701 702 if (cred.cr_ngroups != 0 || cred.cr_uid != geteuid() || 703 cred.cr_gid != getegid()) { 704 705 test_fail("did no receive the proper credentials"); 706 } 707 708 rc = close(dst); 709 if (rc == -1) { 710 test_fail("close"); 711 } 712 713 rc = close(src); 714 if (rc == -1) { 715 test_fail("close"); 716 } 717 718 UNLINK(TEST_SUN_PATH); 719 UNLINK(TEST_SUN_PATHB); 720 } 721 722 static void test_connect(const struct socket_test_info *info) 723 { 724 int i, sd, sds[2], rc; 725 726 /* connect() is already tested throughout test56, but 727 * in most cases the client and server end up on /dev/uds 728 * minor 0 and minor 1. This test opens some sockets first and 729 * then calls test_simple_client_server(). This forces the 730 * client and server minor numbers higher in the descriptor table. 731 */ 732 733 debug("starting test_connect()"); 734 735 sd = socket(AF_UNIX, SOCK_DGRAM, 0); 736 if (sd == -1) { 737 test_fail("couldn't create a socket"); 738 } 739 740 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sds); 741 if (rc == -1) { 742 test_fail("couldn't create a socketpair"); 743 } 744 745 for (i = 0; i < 3; i++) { 746 test_simple_client_server(info, types[i]); 747 } 748 749 rc = close(sds[1]); 750 if (rc == -1) { 751 test_fail("close() failed"); 752 } 753 754 rc = close(sds[0]); 755 if (rc == -1) { 756 test_fail("close() failed"); 757 } 758 759 rc = close(sd); 760 if (rc == -1) { 761 test_fail("close() failed"); 762 } 763 764 debug("exiting test_connect()"); 765 } 766 767 static int test_multiproc_read(void) 768 { 769 /* test that when we fork() a process with an open socket descriptor, 770 * the descriptor in each process points to the same thing. 771 */ 772 773 pid_t pid; 774 int sds[2]; 775 int rc, status; 776 char buf[3]; 777 778 debug("entering test_multiproc_read()"); 779 780 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds); 781 if (rc == -1) { 782 test_fail("socketpair"); 783 return 1; 784 } 785 786 memset(buf, '\0', 3); 787 788 789 /* the signal handler is only used by the client, but we have to 790 * install it now. if we don't the server may signal the client 791 * before the handler is installed. 792 */ 793 debug("installing signal handler"); 794 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 795 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 796 return 1; 797 } 798 799 debug("signal handler installed"); 800 801 server_ready = 0; 802 803 pid = fork(); 804 805 if (pid == -1) { 806 807 test_fail("fork"); 808 return 1; 809 810 } else if (pid == 0) { 811 812 while (server_ready == 0) { 813 debug("waiting for SIGUSR1 from parent"); 814 sleep(1); 815 } 816 817 rc = read(sds[1], buf, 2); 818 if (rc == -1) { 819 test_fail("read"); 820 exit(1); 821 } 822 823 if (!(buf[0] == 'X' && buf[1] == '3')) { 824 test_fail("Didn't read X3"); 825 exit(1); 826 } 827 828 exit(0); 829 } else { 830 831 rc = write(sds[0], "MNX3", 4); 832 if (rc == -1) { 833 test_fail("write"); 834 } 835 836 rc = read(sds[1], buf, 2); 837 if (rc == -1) { 838 test_fail("read"); 839 } 840 841 if (!(buf[0] == 'M' && buf[1] == 'N')) { 842 test_fail("Didn't read MN"); 843 } 844 845 /* time to tell the client to start the test */ 846 kill(pid, SIGUSR1); 847 848 do { 849 rc = waitpid(pid, &status, 0); 850 } while (rc == -1 && errno == EINTR); 851 852 /* we use the exit status to get its error count */ 853 errct += WEXITSTATUS(status); 854 } 855 856 return 0; 857 } 858 859 static int test_multiproc_write(void) 860 { 861 /* test that when we fork() a process with an open socket descriptor, 862 * the descriptor in each process points to the same thing. 863 */ 864 865 pid_t pid; 866 int sds[2]; 867 int rc, status; 868 char buf[7]; 869 870 debug("entering test_multiproc_write()"); 871 872 rc = socketpair(PF_UNIX, SOCK_STREAM, 0, sds); 873 if (rc == -1) { 874 test_fail("socketpair"); 875 return 1; 876 } 877 878 memset(buf, '\0', 7); 879 880 881 /* the signal handler is only used by the client, but we have to 882 * install it now. if we don't the server may signal the client 883 * before the handler is installed. 884 */ 885 debug("installing signal handler"); 886 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 887 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 888 return 1; 889 } 890 891 debug("signal handler installed"); 892 893 server_ready = 0; 894 895 pid = fork(); 896 897 if (pid == -1) { 898 899 test_fail("fork"); 900 return 1; 901 902 } else if (pid == 0) { 903 904 while (server_ready == 0) { 905 debug("waiting for SIGUSR1 from parent"); 906 sleep(1); 907 } 908 909 rc = write(sds[1], "IX3", 3); 910 if (rc == -1) { 911 test_fail("write"); 912 exit(1); 913 } 914 915 rc = read(sds[0], buf, 6); 916 if (rc == -1) { 917 test_fail("read"); 918 exit(1); 919 } 920 921 if (strcmp(buf, "MINIX3") != 0) { 922 test_fail("didn't read MINIX3"); 923 exit(1); 924 } 925 926 exit(0); 927 } else { 928 929 rc = write(sds[1], "MIN", 3); 930 if (rc == -1) { 931 test_fail("write"); 932 } 933 934 /* time to tell the client to start the test */ 935 kill(pid, SIGUSR1); 936 937 do { 938 rc = waitpid(pid, &status, 0); 939 } while (rc == -1 && errno == EINTR); 940 941 /* we use the exit status to get its error count */ 942 errct += WEXITSTATUS(status); 943 } 944 945 return 0; 946 } 947 948 static void test_fd_passing_child(int sd) 949 { 950 int fd, rc; 951 char x = 'x'; 952 struct msghdr msghdr; 953 struct cmsghdr *cmsg; 954 struct iovec iov; 955 char buf[BUFSIZE]; 956 957 memset(buf, '\0', BUFSIZE); 958 959 fd = open(TEST_TXT_FILE, O_CREAT|O_TRUNC|O_RDWR); 960 if (fd == -1) { 961 test_fail("could not open test.txt"); 962 } 963 964 msghdr.msg_name = NULL; 965 msghdr.msg_namelen = 0; 966 967 iov.iov_base = &x; 968 iov.iov_len = 1; 969 msghdr.msg_iov = &iov; 970 msghdr.msg_iovlen = 1; 971 972 msghdr.msg_control = buf; 973 msghdr.msg_controllen = CMSG_SPACE(sizeof(int)); 974 975 msghdr.msg_flags = 0; 976 977 cmsg = CMSG_FIRSTHDR(&msghdr); 978 cmsg->cmsg_len = CMSG_SPACE(sizeof(int)); 979 cmsg->cmsg_level = SOL_SOCKET; 980 cmsg->cmsg_type = SCM_RIGHTS; 981 982 ((int *) CMSG_DATA(cmsg))[0] = fd; 983 984 rc = sendmsg(sd, &msghdr, 0); 985 if (rc == -1) { 986 test_fail("could not send message"); 987 } 988 989 memset(buf, '\0', BUFSIZE); 990 rc = read(sd, buf, BUFSIZE); 991 if (rc == -1) { 992 test_fail("could not read from socket"); 993 } 994 995 if (strcmp(buf, "done") != 0) { 996 test_fail("we didn't read the right message"); 997 } 998 999 memset(buf, '\0', BUFSIZE); 1000 rc = lseek(fd, 0, SEEK_SET); 1001 if (rc == -1) { 1002 test_fail("could not seek to start of test.txt"); 1003 } 1004 1005 rc = read(fd, buf, BUFSIZE); 1006 if (rc == -1) { 1007 test_fail("could not read from test.txt"); 1008 } 1009 1010 if (strcmp(buf, MSG) != 0) { 1011 test_fail("other process didn't write MSG to test.txt"); 1012 } 1013 1014 rc = close(fd); 1015 if (rc == -1) { 1016 test_fail("could not close test.txt"); 1017 } 1018 1019 rc = close(sd); 1020 if (rc == -1) { 1021 test_fail("could not close socket"); 1022 } 1023 1024 rc = unlink(TEST_TXT_FILE); 1025 if (rc == -1) { 1026 test_fail("could not unlink test.txt"); 1027 } 1028 1029 exit(errct); 1030 } 1031 1032 static void test_fd_passing_parent(int sd) 1033 { 1034 int rc, fd; 1035 char x; 1036 struct msghdr msghdr; 1037 struct cmsghdr *cmsg; 1038 struct iovec iov; 1039 char buf[BUFSIZE]; 1040 1041 memset(buf, '\0', BUFSIZE); 1042 1043 msghdr.msg_name = NULL; 1044 msghdr.msg_namelen = 0; 1045 1046 iov.iov_base = &x; 1047 iov.iov_len = 1; 1048 msghdr.msg_iov = &iov; 1049 msghdr.msg_iovlen = 1; 1050 1051 msghdr.msg_iov = &iov; 1052 msghdr.msg_iovlen = 1; 1053 1054 msghdr.msg_control = buf; 1055 msghdr.msg_controllen = BUFSIZE; 1056 1057 msghdr.msg_flags = 0; 1058 1059 rc = recvmsg(sd, &msghdr, 0); 1060 if (rc == -1) { 1061 test_fail("could not recv message."); 1062 } 1063 1064 cmsg = CMSG_FIRSTHDR(&msghdr); 1065 fd = ((int *) CMSG_DATA(cmsg))[0]; 1066 1067 rc = write(fd, MSG, strlen(MSG)); 1068 if (rc != strlen(MSG)) { 1069 test_fail("could not write the full message to test.txt"); 1070 } 1071 1072 rc = close(fd); 1073 if (rc == -1) { 1074 test_fail("could not close test.txt"); 1075 } 1076 1077 memset(buf, '\0', BUFSIZE); 1078 strcpy(buf, "done"); 1079 rc = write(sd, buf, BUFSIZE); 1080 if (rc == -1) { 1081 test_fail("could not write to socket"); 1082 } 1083 1084 rc = close(sd); 1085 if (rc == -1) { 1086 test_fail("could not close socket"); 1087 } 1088 } 1089 1090 static void test_permissions(void) { 1091 /* Test bind and connect for permission verification 1092 * 1093 * After creating a UDS socket we change user credentials. At that 1094 * point we should not be allowed to bind or connect to the UDS socket 1095 */ 1096 1097 pid_t pid; 1098 int sd, rc, status; 1099 struct sockaddr_un addr; 1100 1101 memset(&addr, '\0', sizeof(struct sockaddr_un)); 1102 addr.sun_family = AF_UNIX; 1103 strncpy(addr.sun_path, TEST_SUN_PATH, sizeof(addr.sun_path) - 1); 1104 1105 UNLINK(TEST_SUN_PATH); 1106 1107 pid = fork(); 1108 if (pid < 0) test_fail("unable to fork"); 1109 else if (pid == 0) { 1110 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 1111 if (setuid(999) != 0) test_fail("unable to chance uid"); 1112 rc = bind(sd, (struct sockaddr *) &addr, 1113 sizeof(struct sockaddr_un)); 1114 if (rc != -1) { 1115 test_fail("bind() should not have worked"); 1116 } 1117 exit(errct); 1118 } else { 1119 rc = waitpid(pid, &status, 0); 1120 errct += WEXITSTATUS(status); 1121 } 1122 1123 /* the signal handler is only used by the client, but we have to 1124 * install it now. if we don't the server may signal the client 1125 * before the handler is installed. 1126 */ 1127 debug("installing signal handler"); 1128 if (signal(SIGUSR1, test_xfer_sighdlr) == SIG_ERR) { 1129 test_fail("signal(SIGUSR1, test_xfer_sighdlr) failed"); 1130 } 1131 1132 debug("signal handler installed"); 1133 1134 server_ready = 0; 1135 1136 pid = fork(); 1137 if (pid < 0) test_fail("unable to fork"); 1138 else if (pid == 0) { 1139 while (server_ready == 0) { 1140 debug("[client] waiting for the server to signal"); 1141 sleep(1); 1142 } 1143 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 1144 if (setuid(999) != 0) test_fail("unable to chance uid"); 1145 rc = connect(sd, (struct sockaddr *) &addr, 1146 sizeof(struct sockaddr_un)); 1147 if (rc != -1) 1148 test_fail("connect should not have worked"); 1149 exit(errct); 1150 } else { 1151 SOCKET(sd, PF_UNIX, SOCK_STREAM, 0); 1152 rc = bind(sd, (struct sockaddr *) &addr, 1153 sizeof(struct sockaddr_un)); 1154 if (rc == -1) { 1155 test_fail("bind() should have worked"); 1156 } 1157 1158 rc = listen(sd, 8); 1159 if (rc == -1) { 1160 test_fail("listen(sd, 8) should have worked"); 1161 } 1162 kill(pid, SIGUSR1); 1163 sleep(1); 1164 CLOSE(sd); 1165 1166 rc = waitpid(pid, &status, 0); 1167 errct += WEXITSTATUS(status); 1168 } 1169 1170 UNLINK(TEST_SUN_PATH); 1171 } 1172 1173 static void test_fd_passing(void) { 1174 int status; 1175 int sv[2]; 1176 pid_t pid; 1177 int rc; 1178 1179 rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sv); 1180 if (rc == -1) { 1181 test_fail("socketpair failed"); 1182 } 1183 1184 pid = fork(); 1185 if (pid == -1) { 1186 test_fail("fork() failed"); 1187 1188 rc = close(sv[0]); 1189 if (rc == -1) { 1190 test_fail("could not close sv[0]"); 1191 } 1192 1193 rc = close(sv[1]); 1194 if (rc == -1) { 1195 test_fail("could not close sv[1]"); 1196 } 1197 1198 exit(0); 1199 } else if (pid == 0) { 1200 rc = close(sv[0]); 1201 if (rc == -1) { 1202 test_fail("could not close sv[0]"); 1203 } 1204 1205 test_fd_passing_child(sv[1]); 1206 test_fail("should never get here"); 1207 exit(1); 1208 } else { 1209 rc = close(sv[1]); 1210 if (rc == -1) { 1211 test_fail("could not close sv[1]"); 1212 } 1213 1214 test_fd_passing_parent(sv[0]); 1215 1216 /* wait for client to exit */ 1217 do { 1218 errno = 0; 1219 rc = waitpid(pid, &status, 0); 1220 } while (rc == -1 && errno == EINTR); 1221 1222 /* we use the exit status to get its error count */ 1223 errct += WEXITSTATUS(status); 1224 } 1225 } 1226 1227 static void test_select(void) 1228 { 1229 int nfds = -1; 1230 int socks[2]; 1231 fd_set readfds, writefds; 1232 struct timeval tv; 1233 int res = 0; 1234 char buf[1]; 1235 1236 FD_ZERO(&readfds); 1237 FD_ZERO(&writefds); 1238 1239 tv.tv_sec = 2; 1240 tv.tv_usec = 0; /* 2 sec time out */ 1241 1242 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 1243 test_fail("Can't open socket pair."); 1244 } 1245 FD_SET(socks[0], &readfds); 1246 nfds = socks[0] + 1; 1247 1248 /* Close the write end of the socket to generate EOF on read end */ 1249 if ((res = shutdown(socks[1], SHUT_WR)) != 0) { 1250 test_fail("shutdown failed\n"); 1251 } 1252 1253 res = select(nfds, &readfds, NULL, NULL, &tv); 1254 if (res != 1) { 1255 test_fail("select should've returned 1 ready fd\n"); 1256 } 1257 if (!(FD_ISSET(socks[0], &readfds))) { 1258 test_fail("The server didn't respond within 2 seconds"); 1259 } 1260 /* Now try to read from empty, closed pipe */ 1261 if (read(socks[0], buf, sizeof(buf)) != 0) { 1262 test_fail("reading from empty, closed pipe should return EOF"); 1263 } 1264 1265 close(socks[0]); 1266 1267 /* Try again the other way around: create a socketpair, close the 1268 * read end, and try to write. This should cause an EPIPE */ 1269 1270 tv.tv_sec = 2; 1271 tv.tv_usec = 0; /* 2 sec time out */ 1272 1273 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 1274 test_fail("Can't open socket pair."); 1275 } 1276 FD_SET(socks[1], &writefds); 1277 nfds = socks[1] + 1; 1278 1279 /* kill the read end of the socket to generate EPIPE on write end */ 1280 if ((res = shutdown(socks[0], SHUT_RD)) != 0) { 1281 test_fail("shutdown failed\n"); 1282 } 1283 1284 res = select(nfds, NULL, &writefds, NULL, &tv); 1285 if (res != 1) { 1286 test_fail("select should've returned 1 ready fd\n"); 1287 } 1288 if (!(FD_ISSET(socks[1], &writefds))) { 1289 test_fail("The server didn't respond within 2 seconds"); 1290 } 1291 1292 /* Now try to write to closed pipe */ 1293 errno = 0; 1294 if ((res = write(socks[1], buf, sizeof(buf))) != -1) { 1295 printf("write res = %d\n", res); 1296 test_fail("writing to empty, closed pipe should fail"); 1297 } 1298 if (errno != EPIPE) { 1299 printf("errno = %d\n", errno); 1300 test_fail("writing to closed pipe should return EPIPE\n"); 1301 } 1302 1303 close(socks[1]); 1304 } 1305 1306 static void test_select_close(void) 1307 { 1308 int res, socks[2]; 1309 fd_set readfds; 1310 struct timeval tv; 1311 1312 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 1313 test_fail("Can't open socket pair."); 1314 } 1315 1316 switch (fork()) { 1317 case 0: 1318 sleep(1); 1319 1320 exit(0); 1321 case -1: 1322 test_fail("Can't fork."); 1323 default: 1324 break; 1325 } 1326 1327 close(socks[1]); 1328 1329 FD_ZERO(&readfds); 1330 FD_SET(socks[0], &readfds); 1331 tv.tv_sec = 2; 1332 tv.tv_usec = 0; /* 2 sec time out */ 1333 1334 res = select(socks[0] + 1, &readfds, NULL, NULL, &tv); 1335 if (res != 1) { 1336 test_fail("select should've returned 1 ready fd\n"); 1337 } 1338 if (!(FD_ISSET(socks[0], &readfds))) { 1339 test_fail("The server didn't respond within 2 seconds"); 1340 } 1341 1342 wait(NULL); 1343 1344 close(socks[0]); 1345 } 1346 1347 static void test_fchmod(void) 1348 { 1349 int socks[2]; 1350 struct stat st1, st2; 1351 1352 if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) < 0) { 1353 test_fail("Can't open socket pair."); 1354 } 1355 1356 if (fstat(socks[0], &st1) < 0 || fstat(socks[1], &st2) < 0) { 1357 test_fail("fstat failed."); 1358 } 1359 1360 if ((st1.st_mode & (S_IRUSR|S_IWUSR)) == S_IRUSR && 1361 (st2.st_mode & (S_IRUSR|S_IWUSR)) == S_IWUSR) { 1362 test_fail("fstat failed."); 1363 } 1364 1365 if (fchmod(socks[0], S_IRUSR) < 0 || 1366 fstat(socks[0], &st1) < 0 || 1367 (st1.st_mode & (S_IRUSR|S_IWUSR)) != S_IRUSR) { 1368 test_fail("fchmod/fstat mode set/check failed (1)."); 1369 } 1370 1371 if (fchmod(socks[1], S_IWUSR) < 0 || fstat(socks[1], &st2) < 0 || 1372 (st2.st_mode & (S_IRUSR|S_IWUSR)) != S_IWUSR) { 1373 test_fail("fchmod/fstat mode set/check failed (2)."); 1374 } 1375 1376 close(socks[0]); 1377 close(socks[1]); 1378 } 1379 1380 int main(int argc, char *argv[]) 1381 { 1382 int i; 1383 struct sockaddr_un clientaddr = { 1384 .sun_family = AF_UNIX, 1385 .sun_path = TEST_SUN_PATH, 1386 }; 1387 struct sockaddr_un clientaddr2 = { 1388 .sun_family = AF_UNIX, 1389 .sun_path = TEST_SUN_PATHB, 1390 }; 1391 struct sockaddr_un clientaddrsym = { 1392 .sun_family = AF_UNIX, 1393 .sun_path = TEST_SYM_A, 1394 }; 1395 const struct socket_test_info info = { 1396 .clientaddr = (struct sockaddr *) &clientaddr, 1397 .clientaddrlen = sizeof(clientaddr), 1398 .clientaddr2 = (struct sockaddr *) &clientaddr2, 1399 .clientaddr2len = sizeof(clientaddr2), 1400 .clientaddrsym = (struct sockaddr *) &clientaddrsym, 1401 .clientaddrsymlen = sizeof(clientaddrsym), 1402 .domain = PF_UNIX, 1403 .expected_rcvbuf = PIPE_BUF, 1404 .expected_sndbuf = PIPE_BUF, 1405 .serveraddr = (struct sockaddr *) &clientaddr, 1406 .serveraddrlen = sizeof(clientaddr), 1407 .serveraddr2 = (struct sockaddr *) &clientaddr2, 1408 .serveraddr2len = sizeof(clientaddr2), 1409 .type = SOCK_STREAM, 1410 .types = types, 1411 .typecount = 3, 1412 .callback_check_sockaddr = callback_check_sockaddr, 1413 .callback_cleanup = callback_cleanup, 1414 .callback_xfer_prepclient = callback_xfer_prepclient, 1415 .callback_xfer_peercred = callback_xfer_peercred, 1416 }; 1417 1418 debug("entering main()"); 1419 1420 start(56); 1421 1422 test_socket(&info); 1423 test_bind(&info); 1424 test_bind_unix(); 1425 test_listen(&info); 1426 test_getsockname(&info); 1427 test_header(); 1428 test_shutdown(&info); 1429 test_close(&info); 1430 test_permissions(); 1431 test_dup(&info); 1432 test_dup2(&info); 1433 test_socketpair(); 1434 test_shutdown(&info); 1435 test_read(&info); 1436 test_write(&info); 1437 test_sockopts(&info); 1438 test_ucred(); 1439 test_xfer(&info); 1440 1441 for (i = 0; i < 3; i++) { 1442 test_simple_client_server(&info, types[i]); 1443 if (types[i] != SOCK_DGRAM) test_vectorio(types[i]); 1444 if (types[i] != SOCK_DGRAM) test_msg(types[i]); 1445 } 1446 1447 test_abort_client_server(&info, 1); 1448 test_abort_client_server(&info, 2); 1449 test_msg_dgram(&info); 1450 test_connect(&info); 1451 test_multiproc_read(); 1452 test_multiproc_write(); 1453 test_scm_credentials(); 1454 test_fd_passing(); 1455 test_select(); 1456 test_select_close(); 1457 test_fchmod(); 1458 test_nonblock(&info); 1459 test_connect_nb(&info); 1460 test_intr(&info); 1461 test_connect_close(&info); 1462 test_listen_close(&info); 1463 test_listen_close_nb(&info); 1464 1465 quit(); 1466 1467 return -1; /* we should never get here */ 1468 } 1469