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