1 /*- 2 * Copyright (c) 2018 Aniket Pandey 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * SUCH DAMAGE. 24 * 25 * $FreeBSD$ 26 */ 27 28 #include <sys/types.h> 29 #include <sys/socket.h> 30 #include <sys/stat.h> 31 #include <sys/uio.h> 32 #include <sys/un.h> 33 34 #include <atf-c.h> 35 #include <fcntl.h> 36 #include <stdarg.h> 37 #include <unistd.h> 38 39 #include "utils.h" 40 41 #define MAX_DATA 128 42 #define SERVER_PATH "server" 43 44 static pid_t pid; 45 static mode_t mode = 0777; 46 static int sockfd, sockfd2, connectfd; 47 static ssize_t data_bytes; 48 static socklen_t len = sizeof(struct sockaddr_un); 49 static struct iovec io1, io2; 50 static struct pollfd fds[1]; 51 static struct sockaddr_un server; 52 static struct msghdr sendbuf, recvbuf; 53 static char extregex[MAX_DATA]; 54 static char data[MAX_DATA]; 55 static char msgbuff[MAX_DATA] = "This message does not exist"; 56 static const char *auclass = "nt"; 57 static const char *path = "fileforaudit"; 58 static const char *nosupregex = "return,failure : Address family " 59 "not supported by protocol family"; 60 static const char *invalregex = "return,failure : Bad file descriptor"; 61 62 /* 63 * Initialize iovec structure to be used as a field of struct msghdr 64 */ 65 static void 66 init_iov(struct iovec *io, char msgbuf[], int datalen) 67 { 68 io->iov_base = msgbuf; 69 io->iov_len = datalen; 70 } 71 72 /* 73 * Initialize msghdr structure for communication via datagram sockets 74 */ 75 static void 76 init_msghdr(struct msghdr *hdrbuf, struct iovec *io, struct sockaddr_un *addr) 77 { 78 socklen_t length; 79 80 bzero(hdrbuf, sizeof(*hdrbuf)); 81 length = (socklen_t)sizeof(struct sockaddr_un); 82 hdrbuf->msg_name = addr; 83 hdrbuf->msg_namelen = length; 84 hdrbuf->msg_iov = io; 85 hdrbuf->msg_iovlen = 1; 86 } 87 88 /* 89 * Variadic function to close socket descriptors 90 */ 91 static void 92 close_sockets(int count, ...) 93 { 94 int sockd; 95 va_list socklist; 96 va_start(socklist, count); 97 for (sockd = 0; sockd < count; sockd++) { 98 close(va_arg(socklist, int)); 99 } 100 va_end(socklist); 101 } 102 103 /* 104 * Assign local filesystem address to a Unix domain socket 105 */ 106 static void 107 assign_address(struct sockaddr_un *serveraddr) 108 { 109 memset(serveraddr, 0, sizeof(*serveraddr)); 110 serveraddr->sun_family = AF_UNIX; 111 strcpy(serveraddr->sun_path, SERVER_PATH); 112 } 113 114 115 ATF_TC_WITH_CLEANUP(socket_success); 116 ATF_TC_HEAD(socket_success, tc) 117 { 118 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 119 "socket(2) call"); 120 } 121 122 ATF_TC_BODY(socket_success, tc) 123 { 124 FILE *pipefd = setup(fds, auclass); 125 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 126 /* Check the presence of sockfd in audit record */ 127 snprintf(extregex, sizeof(extregex), "socket.*ret.*success,%d", sockfd); 128 check_audit(fds, extregex, pipefd); 129 close(sockfd); 130 } 131 132 ATF_TC_CLEANUP(socket_success, tc) 133 { 134 cleanup(); 135 } 136 137 138 ATF_TC_WITH_CLEANUP(socket_failure); 139 ATF_TC_HEAD(socket_failure, tc) 140 { 141 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 142 "socket(2) call"); 143 } 144 145 ATF_TC_BODY(socket_failure, tc) 146 { 147 snprintf(extregex, sizeof(extregex), "socket.*%s", nosupregex); 148 FILE *pipefd = setup(fds, auclass); 149 /* Failure reason: Unsupported value of 'domain' argument: 0 */ 150 ATF_REQUIRE_EQ(-1, socket(0, SOCK_STREAM, 0)); 151 check_audit(fds, extregex, pipefd); 152 } 153 154 ATF_TC_CLEANUP(socket_failure, tc) 155 { 156 cleanup(); 157 } 158 159 160 ATF_TC_WITH_CLEANUP(socketpair_success); 161 ATF_TC_HEAD(socketpair_success, tc) 162 { 163 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 164 "socketpair(2) call"); 165 } 166 167 ATF_TC_BODY(socketpair_success, tc) 168 { 169 int sv[2]; 170 FILE *pipefd = setup(fds, auclass); 171 ATF_REQUIRE_EQ(0, socketpair(PF_UNIX, SOCK_STREAM, 0, sv)); 172 173 /* Check for 0x0 (argument 3: default protocol) in the audit record */ 174 snprintf(extregex, sizeof(extregex), "socketpair.*0x0.*return,success"); 175 check_audit(fds, extregex, pipefd); 176 close_sockets(2, sv[0], sv[1]); 177 } 178 179 ATF_TC_CLEANUP(socketpair_success, tc) 180 { 181 cleanup(); 182 } 183 184 185 ATF_TC_WITH_CLEANUP(socketpair_failure); 186 ATF_TC_HEAD(socketpair_failure, tc) 187 { 188 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 189 "socketpair(2) call"); 190 } 191 192 ATF_TC_BODY(socketpair_failure, tc) 193 { 194 snprintf(extregex, sizeof(extregex), "socketpair.*%s", nosupregex); 195 FILE *pipefd = setup(fds, auclass); 196 /* Failure reason: Unsupported value of 'domain' argument: 0 */ 197 ATF_REQUIRE_EQ(-1, socketpair(0, SOCK_STREAM, 0, NULL)); 198 check_audit(fds, extregex, pipefd); 199 } 200 201 ATF_TC_CLEANUP(socketpair_failure, tc) 202 { 203 cleanup(); 204 } 205 206 207 ATF_TC_WITH_CLEANUP(setsockopt_success); 208 ATF_TC_HEAD(setsockopt_success, tc) 209 { 210 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 211 "setsockopt(2) call"); 212 } 213 214 ATF_TC_BODY(setsockopt_success, tc) 215 { 216 int tr = 1; 217 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 218 /* Check the presence of sockfd in audit record */ 219 snprintf(extregex, sizeof(extregex), 220 "setsockopt.*0x%x.*return,success", sockfd); 221 222 FILE *pipefd = setup(fds, auclass); 223 ATF_REQUIRE_EQ(0, setsockopt(sockfd, SOL_SOCKET, 224 SO_REUSEADDR, &tr, sizeof(int))); 225 check_audit(fds, extregex, pipefd); 226 close(sockfd); 227 } 228 229 ATF_TC_CLEANUP(setsockopt_success, tc) 230 { 231 cleanup(); 232 } 233 234 235 ATF_TC_WITH_CLEANUP(setsockopt_failure); 236 ATF_TC_HEAD(setsockopt_failure, tc) 237 { 238 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 239 "setsockopt(2) call"); 240 } 241 242 ATF_TC_BODY(setsockopt_failure, tc) 243 { 244 snprintf(extregex, sizeof(extregex), "setsockopt.*%s", invalregex); 245 FILE *pipefd = setup(fds, auclass); 246 /* Failure reason: Invalid socket descriptor */ 247 ATF_REQUIRE_EQ(-1, setsockopt(-1, SOL_SOCKET, 0, NULL, 0)); 248 check_audit(fds, extregex, pipefd); 249 } 250 251 ATF_TC_CLEANUP(setsockopt_failure, tc) 252 { 253 cleanup(); 254 } 255 256 257 ATF_TC_WITH_CLEANUP(bind_success); 258 ATF_TC_HEAD(bind_success, tc) 259 { 260 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 261 "bind(2) call"); 262 } 263 264 ATF_TC_BODY(bind_success, tc) 265 { 266 assign_address(&server); 267 /* Preliminary socket setup */ 268 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 269 /* Check the presence of AF_UNIX address path in audit record */ 270 snprintf(extregex, sizeof(extregex), 271 "bind.*unix.*%s.*return,success", SERVER_PATH); 272 273 FILE *pipefd = setup(fds, auclass); 274 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 275 check_audit(fds, extregex, pipefd); 276 close(sockfd); 277 } 278 279 ATF_TC_CLEANUP(bind_success, tc) 280 { 281 cleanup(); 282 } 283 284 285 ATF_TC_WITH_CLEANUP(bind_failure); 286 ATF_TC_HEAD(bind_failure, tc) 287 { 288 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 289 "bind(2) call"); 290 } 291 292 ATF_TC_BODY(bind_failure, tc) 293 { 294 assign_address(&server); 295 /* Check the presence of AF_UNIX path in audit record */ 296 snprintf(extregex, sizeof(extregex), 297 "bind.*%s.*return,failure", SERVER_PATH); 298 299 FILE *pipefd = setup(fds, auclass); 300 /* Failure reason: Invalid socket descriptor */ 301 ATF_REQUIRE_EQ(-1, bind(0, (struct sockaddr *)&server, len)); 302 check_audit(fds, extregex, pipefd); 303 } 304 305 ATF_TC_CLEANUP(bind_failure, tc) 306 { 307 cleanup(); 308 } 309 310 311 ATF_TC_WITH_CLEANUP(bindat_success); 312 ATF_TC_HEAD(bindat_success, tc) 313 { 314 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 315 "bindat(2) call"); 316 } 317 318 ATF_TC_BODY(bindat_success, tc) 319 { 320 assign_address(&server); 321 /* Preliminary socket setup */ 322 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 323 /* Check the presence of socket descriptor in audit record */ 324 snprintf(extregex, sizeof(extregex), 325 "bindat.*0x%x.*return,success", sockfd); 326 327 FILE *pipefd = setup(fds, auclass); 328 ATF_REQUIRE_EQ(0, bindat(AT_FDCWD, sockfd, 329 (struct sockaddr *)&server, len)); 330 check_audit(fds, extregex, pipefd); 331 close(sockfd); 332 } 333 334 ATF_TC_CLEANUP(bindat_success, tc) 335 { 336 cleanup(); 337 } 338 339 340 ATF_TC_WITH_CLEANUP(bindat_failure); 341 ATF_TC_HEAD(bindat_failure, tc) 342 { 343 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 344 "bindat(2) call"); 345 } 346 347 ATF_TC_BODY(bindat_failure, tc) 348 { 349 assign_address(&server); 350 snprintf(extregex, sizeof(extregex), "bindat.*%s", invalregex); 351 352 FILE *pipefd = setup(fds, auclass); 353 /* Failure reason: Invalid socket descriptor */ 354 ATF_REQUIRE_EQ(-1, bindat(AT_FDCWD, -1, 355 (struct sockaddr *)&server, len)); 356 check_audit(fds, extregex, pipefd); 357 } 358 359 ATF_TC_CLEANUP(bindat_failure, tc) 360 { 361 cleanup(); 362 } 363 364 365 ATF_TC_WITH_CLEANUP(listen_success); 366 ATF_TC_HEAD(listen_success, tc) 367 { 368 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 369 "listen(2) call"); 370 } 371 372 ATF_TC_BODY(listen_success, tc) 373 { 374 assign_address(&server); 375 /* Preliminary socket setup */ 376 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 377 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 378 /* Check the presence of socket descriptor in the audit record */ 379 snprintf(extregex, sizeof(extregex), 380 "listen.*0x%x.*return,success", sockfd); 381 382 FILE *pipefd = setup(fds, auclass); 383 ATF_REQUIRE_EQ(0, listen(sockfd, 1)); 384 check_audit(fds, extregex, pipefd); 385 close(sockfd); 386 } 387 388 ATF_TC_CLEANUP(listen_success, tc) 389 { 390 cleanup(); 391 } 392 393 394 ATF_TC_WITH_CLEANUP(listen_failure); 395 ATF_TC_HEAD(listen_failure, tc) 396 { 397 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 398 "listen(2) call"); 399 } 400 401 ATF_TC_BODY(listen_failure, tc) 402 { 403 snprintf(extregex, sizeof(extregex), "listen.*%s", invalregex); 404 FILE *pipefd = setup(fds, auclass); 405 /* Failure reason: Invalid socket descriptor */ 406 ATF_REQUIRE_EQ(-1, listen(-1, 1)); 407 check_audit(fds, extregex, pipefd); 408 } 409 410 ATF_TC_CLEANUP(listen_failure, tc) 411 { 412 cleanup(); 413 } 414 415 416 ATF_TC_WITH_CLEANUP(connect_success); 417 ATF_TC_HEAD(connect_success, tc) 418 { 419 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 420 "connect(2) call"); 421 } 422 423 ATF_TC_BODY(connect_success, tc) 424 { 425 assign_address(&server); 426 /* Setup a server socket and bind to the specified address */ 427 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 428 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 429 ATF_REQUIRE_EQ(0, listen(sockfd, 1)); 430 431 /* Set up "blocking" client socket */ 432 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 433 434 /* Audit record must contain AF_UNIX address path & sockfd2 */ 435 snprintf(extregex, sizeof(extregex), 436 "connect.*0x%x.*%s.*success", sockfd2, SERVER_PATH); 437 438 FILE *pipefd = setup(fds, auclass); 439 ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); 440 check_audit(fds, extregex, pipefd); 441 442 /* Close all socket descriptors */ 443 close_sockets(2, sockfd, sockfd2); 444 } 445 446 ATF_TC_CLEANUP(connect_success, tc) 447 { 448 cleanup(); 449 } 450 451 452 ATF_TC_WITH_CLEANUP(connect_failure); 453 ATF_TC_HEAD(connect_failure, tc) 454 { 455 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 456 "connect(2) call"); 457 } 458 459 ATF_TC_BODY(connect_failure, tc) 460 { 461 assign_address(&server); 462 /* Audit record must contain AF_UNIX address path */ 463 snprintf(extregex, sizeof(extregex), 464 "connect.*%s.*return,failure", SERVER_PATH); 465 466 FILE *pipefd = setup(fds, auclass); 467 /* Failure reason: Invalid socket descriptor */ 468 ATF_REQUIRE_EQ(-1, connect(-1, (struct sockaddr *)&server, len)); 469 check_audit(fds, extregex, pipefd); 470 } 471 472 ATF_TC_CLEANUP(connect_failure, tc) 473 { 474 cleanup(); 475 } 476 477 478 ATF_TC_WITH_CLEANUP(connectat_success); 479 ATF_TC_HEAD(connectat_success, tc) 480 { 481 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 482 "connectat(2) call"); 483 } 484 485 ATF_TC_BODY(connectat_success, tc) 486 { 487 assign_address(&server); 488 /* Setup a server socket and bind to the specified address */ 489 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 490 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 491 ATF_REQUIRE_EQ(0, listen(sockfd, 1)); 492 493 /* Set up "blocking" client socket */ 494 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 495 496 /* Audit record must contain sockfd2 */ 497 snprintf(extregex, sizeof(extregex), 498 "connectat.*0x%x.*return,success", sockfd2); 499 500 FILE *pipefd = setup(fds, auclass); 501 ATF_REQUIRE_EQ(0, connectat(AT_FDCWD, sockfd2, 502 (struct sockaddr *)&server, len)); 503 check_audit(fds, extregex, pipefd); 504 505 /* Close all socket descriptors */ 506 close_sockets(2, sockfd, sockfd2); 507 } 508 509 ATF_TC_CLEANUP(connectat_success, tc) 510 { 511 cleanup(); 512 } 513 514 515 ATF_TC_WITH_CLEANUP(connectat_failure); 516 ATF_TC_HEAD(connectat_failure, tc) 517 { 518 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 519 "connectat(2) call"); 520 } 521 522 ATF_TC_BODY(connectat_failure, tc) 523 { 524 assign_address(&server); 525 snprintf(extregex, sizeof(extregex), "connectat.*%s", invalregex); 526 527 FILE *pipefd = setup(fds, auclass); 528 /* Failure reason: Invalid socket descriptor */ 529 ATF_REQUIRE_EQ(-1, connectat(AT_FDCWD, -1, 530 (struct sockaddr *)&server, len)); 531 check_audit(fds, extregex, pipefd); 532 } 533 534 ATF_TC_CLEANUP(connectat_failure, tc) 535 { 536 cleanup(); 537 } 538 539 540 ATF_TC_WITH_CLEANUP(accept_success); 541 ATF_TC_HEAD(accept_success, tc) 542 { 543 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 544 "accept(2) call"); 545 } 546 547 ATF_TC_BODY(accept_success, tc) 548 { 549 assign_address(&server); 550 /* Setup a server socket and bind to the specified address */ 551 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 552 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 553 ATF_REQUIRE_EQ(0, listen(sockfd, 1)); 554 555 /* Set up "blocking" client socket */ 556 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 557 ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); 558 559 FILE *pipefd = setup(fds, auclass); 560 ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); 561 562 /* Audit record must contain connectfd & sockfd */ 563 snprintf(extregex, sizeof(extregex), 564 "accept.*0x%x.*return,success,%d", sockfd, connectfd); 565 check_audit(fds, extregex, pipefd); 566 567 /* Close all socket descriptors */ 568 close_sockets(3, sockfd, sockfd2, connectfd); 569 } 570 571 ATF_TC_CLEANUP(accept_success, tc) 572 { 573 cleanup(); 574 } 575 576 577 ATF_TC_WITH_CLEANUP(accept_failure); 578 ATF_TC_HEAD(accept_failure, tc) 579 { 580 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 581 "accept(2) call"); 582 } 583 584 ATF_TC_BODY(accept_failure, tc) 585 { 586 snprintf(extregex, sizeof(extregex), "accept.*%s", invalregex); 587 FILE *pipefd = setup(fds, auclass); 588 /* Failure reason: Invalid socket descriptor */ 589 ATF_REQUIRE_EQ(-1, accept(-1, NULL, NULL)); 590 check_audit(fds, extregex, pipefd); 591 } 592 593 ATF_TC_CLEANUP(accept_failure, tc) 594 { 595 cleanup(); 596 } 597 598 599 ATF_TC_WITH_CLEANUP(send_success); 600 ATF_TC_HEAD(send_success, tc) 601 { 602 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 603 "send(2) call"); 604 } 605 606 ATF_TC_BODY(send_success, tc) 607 { 608 assign_address(&server); 609 /* Setup a server socket and bind to the specified address */ 610 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 611 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 612 ATF_REQUIRE_EQ(0, listen(sockfd, 1)); 613 614 /* Set up "blocking" client and connect with non-blocking server */ 615 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 616 ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); 617 ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); 618 619 /* Send a sample message to the connected socket */ 620 FILE *pipefd = setup(fds, auclass); 621 ATF_REQUIRE((data_bytes = 622 send(sockfd2, msgbuff, strlen(msgbuff), 0)) != -1); 623 624 /* Audit record must contain sockfd2 and data_bytes */ 625 snprintf(extregex, sizeof(extregex), 626 "send.*0x%x.*return,success,%zd", sockfd2, data_bytes); 627 check_audit(fds, extregex, pipefd); 628 629 /* Close all socket descriptors */ 630 close_sockets(3, sockfd, sockfd2, connectfd); 631 } 632 633 ATF_TC_CLEANUP(send_success, tc) 634 { 635 cleanup(); 636 } 637 638 639 ATF_TC_WITH_CLEANUP(send_failure); 640 ATF_TC_HEAD(send_failure, tc) 641 { 642 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 643 "send(2) call"); 644 } 645 646 ATF_TC_BODY(send_failure, tc) 647 { 648 snprintf(extregex, sizeof(extregex), "send.*%s", invalregex); 649 FILE *pipefd = setup(fds, auclass); 650 /* Failure reason: Invalid socket descriptor */ 651 ATF_REQUIRE_EQ(-1, send(-1, NULL, 0, 0)); 652 check_audit(fds, extregex, pipefd); 653 } 654 655 ATF_TC_CLEANUP(send_failure, tc) 656 { 657 cleanup(); 658 } 659 660 661 ATF_TC_WITH_CLEANUP(recv_success); 662 ATF_TC_HEAD(recv_success, tc) 663 { 664 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 665 "recv(2) call"); 666 } 667 668 ATF_TC_BODY(recv_success, tc) 669 { 670 assign_address(&server); 671 /* Setup a server socket and bind to the specified address */ 672 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 673 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 674 ATF_REQUIRE_EQ(0, listen(sockfd, 1)); 675 676 /* Set up "blocking" client and connect with non-blocking server */ 677 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 678 ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); 679 ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); 680 /* Send a sample message to the connected socket */ 681 ATF_REQUIRE(send(sockfd2, msgbuff, strlen(msgbuff), 0) != -1); 682 683 /* Receive data once connectfd is ready for reading */ 684 FILE *pipefd = setup(fds, auclass); 685 ATF_REQUIRE((data_bytes = recv(connectfd, data, MAX_DATA, 0)) != 0); 686 687 /* Audit record must contain connectfd and data_bytes */ 688 snprintf(extregex, sizeof(extregex), 689 "recv.*0x%x.*return,success,%zd", connectfd, data_bytes); 690 check_audit(fds, extregex, pipefd); 691 692 /* Close all socket descriptors */ 693 close_sockets(3, sockfd, sockfd2, connectfd); 694 } 695 696 ATF_TC_CLEANUP(recv_success, tc) 697 { 698 cleanup(); 699 } 700 701 702 ATF_TC_WITH_CLEANUP(recv_failure); 703 ATF_TC_HEAD(recv_failure, tc) 704 { 705 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 706 "recv(2) call"); 707 } 708 709 ATF_TC_BODY(recv_failure, tc) 710 { 711 snprintf(extregex, sizeof(extregex), "recv.*%s", invalregex); 712 FILE *pipefd = setup(fds, auclass); 713 /* Failure reason: Invalid socket descriptor */ 714 ATF_REQUIRE_EQ(-1, recv(-1, NULL, 0, 0)); 715 check_audit(fds, extregex, pipefd); 716 } 717 718 ATF_TC_CLEANUP(recv_failure, tc) 719 { 720 cleanup(); 721 } 722 723 724 ATF_TC_WITH_CLEANUP(sendto_success); 725 ATF_TC_HEAD(sendto_success, tc) 726 { 727 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 728 "sendto(2) call"); 729 } 730 731 ATF_TC_BODY(sendto_success, tc) 732 { 733 assign_address(&server); 734 /* Setup a server socket and bind to the specified address */ 735 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 736 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 737 738 /* Set up client socket to be used for sending the data */ 739 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 740 741 /* Send a sample message to server's address */ 742 FILE *pipefd = setup(fds, auclass); 743 ATF_REQUIRE((data_bytes = sendto(sockfd2, msgbuff, 744 strlen(msgbuff), 0, (struct sockaddr *)&server, len)) != -1); 745 746 /* Audit record must contain sockfd2 and data_bytes */ 747 snprintf(extregex, sizeof(extregex), 748 "sendto.*0x%x.*return,success,%zd", sockfd2, data_bytes); 749 check_audit(fds, extregex, pipefd); 750 751 /* Close all socket descriptors */ 752 close_sockets(2, sockfd, sockfd2); 753 } 754 755 ATF_TC_CLEANUP(sendto_success, tc) 756 { 757 cleanup(); 758 } 759 760 761 ATF_TC_WITH_CLEANUP(sendto_failure); 762 ATF_TC_HEAD(sendto_failure, tc) 763 { 764 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 765 "sendto(2) call"); 766 } 767 768 ATF_TC_BODY(sendto_failure, tc) 769 { 770 snprintf(extregex, sizeof(extregex), "sendto.*%s", invalregex); 771 FILE *pipefd = setup(fds, auclass); 772 /* Failure reason: Invalid socket descriptor */ 773 ATF_REQUIRE_EQ(-1, sendto(-1, NULL, 0, 0, NULL, 0)); 774 check_audit(fds, extregex, pipefd); 775 } 776 777 ATF_TC_CLEANUP(sendto_failure, tc) 778 { 779 cleanup(); 780 } 781 782 783 ATF_TC_WITH_CLEANUP(recvfrom_success); 784 ATF_TC_HEAD(recvfrom_success, tc) 785 { 786 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 787 "recvfrom(2) call"); 788 } 789 790 ATF_TC_BODY(recvfrom_success, tc) 791 { 792 assign_address(&server); 793 /* Setup a server socket and bind to the specified address */ 794 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 795 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 796 797 /* Set up client socket to be used for sending the data */ 798 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 799 ATF_REQUIRE(sendto(sockfd2, msgbuff, strlen(msgbuff), 0, 800 (struct sockaddr *)&server, len) != -1); 801 802 /* Receive data once sockfd is ready for reading */ 803 FILE *pipefd = setup(fds, auclass); 804 ATF_REQUIRE((data_bytes = recvfrom(sockfd, data, 805 MAX_DATA, 0, NULL, &len)) != 0); 806 807 /* Audit record must contain sockfd and data_bytes */ 808 snprintf(extregex, sizeof(extregex), 809 "recvfrom.*0x%x.*return,success,%zd", sockfd, data_bytes); 810 check_audit(fds, extregex, pipefd); 811 812 /* Close all socket descriptors */ 813 close_sockets(2, sockfd, sockfd2); 814 } 815 816 ATF_TC_CLEANUP(recvfrom_success, tc) 817 { 818 cleanup(); 819 } 820 821 822 ATF_TC_WITH_CLEANUP(recvfrom_failure); 823 ATF_TC_HEAD(recvfrom_failure, tc) 824 { 825 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 826 "recvfrom(2) call"); 827 } 828 829 ATF_TC_BODY(recvfrom_failure, tc) 830 { 831 snprintf(extregex, sizeof(extregex), "recvfrom.*%s", invalregex); 832 FILE *pipefd = setup(fds, auclass); 833 /* Failure reason: Invalid socket descriptor */ 834 ATF_REQUIRE_EQ(-1, recvfrom(-1, NULL, 0, 0, NULL, NULL)); 835 check_audit(fds, extregex, pipefd); 836 } 837 838 ATF_TC_CLEANUP(recvfrom_failure, tc) 839 { 840 cleanup(); 841 } 842 843 844 ATF_TC_WITH_CLEANUP(sendmsg_success); 845 ATF_TC_HEAD(sendmsg_success, tc) 846 { 847 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 848 "recvmsg(2) call"); 849 } 850 851 ATF_TC_BODY(sendmsg_success, tc) 852 { 853 assign_address(&server); 854 /* Create a datagram server socket & bind to UNIX address family */ 855 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 856 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 857 858 /* Message buffer to be sent to the server */ 859 init_iov(&io1, msgbuff, sizeof(msgbuff)); 860 init_msghdr(&sendbuf, &io1, &server); 861 862 /* Set up UDP client to communicate with the server */ 863 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 864 865 /* Send a sample message to the specified client address */ 866 FILE *pipefd = setup(fds, auclass); 867 ATF_REQUIRE((data_bytes = sendmsg(sockfd2, &sendbuf, 0)) != -1); 868 869 /* Audit record must contain sockfd2 and data_bytes */ 870 snprintf(extregex, sizeof(extregex), 871 "sendmsg.*0x%x.*return,success,%zd", sockfd2, data_bytes); 872 check_audit(fds, extregex, pipefd); 873 874 /* Close all socket descriptors */ 875 close_sockets(2, sockfd, sockfd2); 876 } 877 878 ATF_TC_CLEANUP(sendmsg_success, tc) 879 { 880 cleanup(); 881 } 882 883 884 ATF_TC_WITH_CLEANUP(sendmsg_failure); 885 ATF_TC_HEAD(sendmsg_failure, tc) 886 { 887 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 888 "sendmsg(2) call"); 889 } 890 891 ATF_TC_BODY(sendmsg_failure, tc) 892 { 893 snprintf(extregex, sizeof(extregex), 894 "sendmsg.*return,failure : Bad address"); 895 FILE *pipefd = setup(fds, auclass); 896 ATF_REQUIRE_EQ(-1, sendmsg(-1, NULL, 0)); 897 check_audit(fds, extregex, pipefd); 898 } 899 900 ATF_TC_CLEANUP(sendmsg_failure, tc) 901 { 902 cleanup(); 903 } 904 905 906 ATF_TC_WITH_CLEANUP(recvmsg_success); 907 ATF_TC_HEAD(recvmsg_success, tc) 908 { 909 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 910 "recvmsg(2) call"); 911 } 912 913 ATF_TC_BODY(recvmsg_success, tc) 914 { 915 assign_address(&server); 916 /* Create a datagram server socket & bind to UNIX address family */ 917 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 918 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 919 920 /* Message buffer to be sent to the server */ 921 init_iov(&io1, msgbuff, sizeof(msgbuff)); 922 init_msghdr(&sendbuf, &io1, &server); 923 924 /* Prepare buffer to store the received data in */ 925 init_iov(&io2, data, sizeof(data)); 926 init_msghdr(&recvbuf, &io2, NULL); 927 928 /* Set up UDP client to communicate with the server */ 929 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1); 930 /* Send a sample message to the connected socket */ 931 ATF_REQUIRE(sendmsg(sockfd2, &sendbuf, 0) != -1); 932 933 /* Receive data once clientfd is ready for reading */ 934 FILE *pipefd = setup(fds, auclass); 935 ATF_REQUIRE((data_bytes = recvmsg(sockfd, &recvbuf, 0)) != -1); 936 937 /* Audit record must contain sockfd and data_bytes */ 938 snprintf(extregex, sizeof(extregex), 939 "recvmsg.*%#x.*return,success,%zd", sockfd, data_bytes); 940 check_audit(fds, extregex, pipefd); 941 942 /* Close all socket descriptors */ 943 close_sockets(2, sockfd, sockfd2); 944 } 945 946 ATF_TC_CLEANUP(recvmsg_success, tc) 947 { 948 cleanup(); 949 } 950 951 952 ATF_TC_WITH_CLEANUP(recvmsg_failure); 953 ATF_TC_HEAD(recvmsg_failure, tc) 954 { 955 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 956 "recvmsg(2) call"); 957 } 958 959 ATF_TC_BODY(recvmsg_failure, tc) 960 { 961 snprintf(extregex, sizeof(extregex), 962 "recvmsg.*return,failure : Bad address"); 963 FILE *pipefd = setup(fds, auclass); 964 ATF_REQUIRE_EQ(-1, recvmsg(-1, NULL, 0)); 965 check_audit(fds, extregex, pipefd); 966 } 967 968 ATF_TC_CLEANUP(recvmsg_failure, tc) 969 { 970 cleanup(); 971 } 972 973 974 ATF_TC_WITH_CLEANUP(shutdown_success); 975 ATF_TC_HEAD(shutdown_success, tc) 976 { 977 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 978 "shutdown(2) call"); 979 } 980 981 ATF_TC_BODY(shutdown_success, tc) 982 { 983 assign_address(&server); 984 /* Setup server socket and bind to the specified address */ 985 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 986 ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len)); 987 ATF_REQUIRE_EQ(0, listen(sockfd, 1)); 988 989 /* Setup client and connect with the blocking server */ 990 ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 991 ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len)); 992 ATF_REQUIRE((connectfd = accept(sockfd, NULL, &len)) != -1); 993 994 /* Audit record must contain clientfd */ 995 snprintf(extregex, sizeof(extregex), 996 "shutdown.*%#x.*return,success", connectfd); 997 998 FILE *pipefd = setup(fds, auclass); 999 ATF_REQUIRE_EQ(0, shutdown(connectfd, SHUT_RDWR)); 1000 check_audit(fds, extregex, pipefd); 1001 1002 /* Close all socket descriptors */ 1003 close_sockets(3, sockfd, sockfd2, connectfd); 1004 } 1005 1006 ATF_TC_CLEANUP(shutdown_success, tc) 1007 { 1008 cleanup(); 1009 } 1010 1011 1012 ATF_TC_WITH_CLEANUP(shutdown_failure); 1013 ATF_TC_HEAD(shutdown_failure, tc) 1014 { 1015 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 1016 "shutdown(2) call"); 1017 } 1018 1019 ATF_TC_BODY(shutdown_failure, tc) 1020 { 1021 pid = getpid(); 1022 snprintf(extregex, sizeof(extregex), 1023 "shutdown.*%d.*return,failure", pid); 1024 1025 FILE *pipefd = setup(fds, auclass); 1026 /* Failure reason: Invalid socket descriptor */ 1027 ATF_REQUIRE_EQ(-1, shutdown(-1, SHUT_RDWR)); 1028 check_audit(fds, extregex, pipefd); 1029 } 1030 1031 ATF_TC_CLEANUP(shutdown_failure, tc) 1032 { 1033 cleanup(); 1034 } 1035 1036 1037 ATF_TC_WITH_CLEANUP(sendfile_success); 1038 ATF_TC_HEAD(sendfile_success, tc) 1039 { 1040 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 1041 "sendfile(2) call"); 1042 } 1043 1044 ATF_TC_BODY(sendfile_success, tc) 1045 { 1046 int filedesc; 1047 ATF_REQUIRE((filedesc = open(path, O_CREAT | O_RDONLY, mode)) != -1); 1048 /* Create a simple UNIX socket to send out random data */ 1049 ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1); 1050 /* Check the presence of sockfd, non-file in the audit record */ 1051 snprintf(extregex, sizeof(extregex), 1052 "sendfile.*%#x,non-file.*return,success", filedesc); 1053 1054 FILE *pipefd = setup(fds, auclass); 1055 ATF_REQUIRE_EQ(0, sendfile(filedesc, sockfd, 0, 0, NULL, NULL, 0)); 1056 check_audit(fds, extregex, pipefd); 1057 1058 /* Teardown socket and file descriptors */ 1059 close_sockets(2, sockfd, filedesc); 1060 } 1061 1062 ATF_TC_CLEANUP(sendfile_success, tc) 1063 { 1064 cleanup(); 1065 } 1066 1067 1068 ATF_TC_WITH_CLEANUP(sendfile_failure); 1069 ATF_TC_HEAD(sendfile_failure, tc) 1070 { 1071 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 1072 "sendfile(2) call"); 1073 } 1074 1075 ATF_TC_BODY(sendfile_failure, tc) 1076 { 1077 pid = getpid(); 1078 snprintf(extregex, sizeof(extregex), 1079 "sendfile.*%d.*return,failure", pid); 1080 FILE *pipefd = setup(fds, auclass); 1081 ATF_REQUIRE_EQ(-1, sendfile(-1, -1, 0, 0, NULL, NULL, 0)); 1082 check_audit(fds, extregex, pipefd); 1083 } 1084 1085 ATF_TC_CLEANUP(sendfile_failure, tc) 1086 { 1087 cleanup(); 1088 } 1089 1090 1091 ATF_TC_WITH_CLEANUP(setfib_success); 1092 ATF_TC_HEAD(setfib_success, tc) 1093 { 1094 atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful " 1095 "setfib(2) call"); 1096 } 1097 1098 ATF_TC_BODY(setfib_success, tc) 1099 { 1100 pid = getpid(); 1101 snprintf(extregex, sizeof(extregex), "setfib.*%d.*return,success", pid); 1102 1103 FILE *pipefd = setup(fds, auclass); 1104 ATF_REQUIRE_EQ(0, setfib(0)); 1105 check_audit(fds, extregex, pipefd); 1106 } 1107 1108 ATF_TC_CLEANUP(setfib_success, tc) 1109 { 1110 cleanup(); 1111 } 1112 1113 1114 ATF_TC_WITH_CLEANUP(setfib_failure); 1115 ATF_TC_HEAD(setfib_failure, tc) 1116 { 1117 atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful " 1118 "setfib(2) call"); 1119 } 1120 1121 ATF_TC_BODY(setfib_failure, tc) 1122 { 1123 pid = getpid(); 1124 snprintf(extregex, sizeof(extregex), "setfib.*%d.*return,failure", pid); 1125 1126 FILE *pipefd = setup(fds, auclass); 1127 ATF_REQUIRE_EQ(-1, setfib(-1)); 1128 check_audit(fds, extregex, pipefd); 1129 } 1130 1131 ATF_TC_CLEANUP(setfib_failure, tc) 1132 { 1133 cleanup(); 1134 } 1135 1136 1137 ATF_TP_ADD_TCS(tp) 1138 { 1139 ATF_TP_ADD_TC(tp, socket_success); 1140 ATF_TP_ADD_TC(tp, socket_failure); 1141 ATF_TP_ADD_TC(tp, socketpair_success); 1142 ATF_TP_ADD_TC(tp, socketpair_failure); 1143 ATF_TP_ADD_TC(tp, setsockopt_success); 1144 ATF_TP_ADD_TC(tp, setsockopt_failure); 1145 1146 ATF_TP_ADD_TC(tp, bind_success); 1147 ATF_TP_ADD_TC(tp, bind_failure); 1148 ATF_TP_ADD_TC(tp, bindat_success); 1149 ATF_TP_ADD_TC(tp, bindat_failure); 1150 ATF_TP_ADD_TC(tp, listen_success); 1151 ATF_TP_ADD_TC(tp, listen_failure); 1152 1153 ATF_TP_ADD_TC(tp, connect_success); 1154 ATF_TP_ADD_TC(tp, connect_failure); 1155 ATF_TP_ADD_TC(tp, connectat_success); 1156 ATF_TP_ADD_TC(tp, connectat_failure); 1157 ATF_TP_ADD_TC(tp, accept_success); 1158 ATF_TP_ADD_TC(tp, accept_failure); 1159 1160 ATF_TP_ADD_TC(tp, send_success); 1161 ATF_TP_ADD_TC(tp, send_failure); 1162 ATF_TP_ADD_TC(tp, recv_success); 1163 ATF_TP_ADD_TC(tp, recv_failure); 1164 1165 ATF_TP_ADD_TC(tp, sendto_success); 1166 ATF_TP_ADD_TC(tp, sendto_failure); 1167 ATF_TP_ADD_TC(tp, recvfrom_success); 1168 ATF_TP_ADD_TC(tp, recvfrom_failure); 1169 1170 ATF_TP_ADD_TC(tp, sendmsg_success); 1171 ATF_TP_ADD_TC(tp, sendmsg_failure); 1172 ATF_TP_ADD_TC(tp, recvmsg_success); 1173 ATF_TP_ADD_TC(tp, recvmsg_failure); 1174 1175 ATF_TP_ADD_TC(tp, shutdown_success); 1176 ATF_TP_ADD_TC(tp, shutdown_failure); 1177 ATF_TP_ADD_TC(tp, sendfile_success); 1178 ATF_TP_ADD_TC(tp, sendfile_failure); 1179 ATF_TP_ADD_TC(tp, setfib_success); 1180 ATF_TP_ADD_TC(tp, setfib_failure); 1181 1182 return (atf_no_error()); 1183 } 1184