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 42static pid_t pid; 43static mode_t mode = 0777; 44static int sockfd, sockfd2, connectfd; 45static ssize_t data_bytes; 46static socklen_t len = sizeof(struct sockaddr_un); 47static struct iovec io1, io2; 48static struct pollfd fds[1]; 49static struct sockaddr_un server; 50static struct msghdr sendbuf, recvbuf; 51static char extregex[MAX_DATA]; 52static char data[MAX_DATA]; 53static char msgbuff[MAX_DATA] = "This message does not exist"; 54static const char *auclass = "nt"; 55static const char *path = "fileforaudit"; 56static const char *nosupregex = "return,failure : Address family " 57 "not supported by protocol family"; 58static const char *invalregex = "return,failure : Bad file descriptor"; 59 60/* 61 * Initialize iovec structure to be used as a field of struct msghdr 62 */ 63static void 64init_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 */ 73static void 74init_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 */ 89static void 90close_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 */ 104static void 105assign_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 113ATF_TC_WITH_CLEANUP(socket_success); 114ATF_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 120ATF_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 130ATF_TC_CLEANUP(socket_success, tc) 131{ 132 cleanup(); 133} 134 135 136ATF_TC_WITH_CLEANUP(socket_failure); 137ATF_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 143ATF_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 152ATF_TC_CLEANUP(socket_failure, tc) 153{ 154 cleanup(); 155} 156 157 158ATF_TC_WITH_CLEANUP(socketpair_success); 159ATF_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 165ATF_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 177ATF_TC_CLEANUP(socketpair_success, tc) 178{ 179 cleanup(); 180} 181 182 183ATF_TC_WITH_CLEANUP(socketpair_failure); 184ATF_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 190ATF_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 199ATF_TC_CLEANUP(socketpair_failure, tc) 200{ 201 cleanup(); 202} 203 204 205ATF_TC_WITH_CLEANUP(setsockopt_success); 206ATF_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 212ATF_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 227ATF_TC_CLEANUP(setsockopt_success, tc) 228{ 229 cleanup(); 230} 231 232 233ATF_TC_WITH_CLEANUP(setsockopt_failure); 234ATF_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 240ATF_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 249ATF_TC_CLEANUP(setsockopt_failure, tc) 250{ 251 cleanup(); 252} 253 254 255ATF_TC_WITH_CLEANUP(bind_success); 256ATF_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 262ATF_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 277ATF_TC_CLEANUP(bind_success, tc) 278{ 279 cleanup(); 280} 281 282 283ATF_TC_WITH_CLEANUP(bind_failure); 284ATF_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 290ATF_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 303ATF_TC_CLEANUP(bind_failure, tc) 304{ 305 cleanup(); 306} 307 308 309ATF_TC_WITH_CLEANUP(bindat_success); 310ATF_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 316ATF_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 332ATF_TC_CLEANUP(bindat_success, tc) 333{ 334 cleanup(); 335} 336 337 338ATF_TC_WITH_CLEANUP(bindat_failure); 339ATF_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 345ATF_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 357ATF_TC_CLEANUP(bindat_failure, tc) 358{ 359 cleanup(); 360} 361 362 363ATF_TC_WITH_CLEANUP(listen_success); 364ATF_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 370ATF_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 386ATF_TC_CLEANUP(listen_success, tc) 387{ 388 cleanup(); 389} 390 391 392ATF_TC_WITH_CLEANUP(listen_failure); 393ATF_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 399ATF_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 408ATF_TC_CLEANUP(listen_failure, tc) 409{ 410 cleanup(); 411} 412 413 414ATF_TC_WITH_CLEANUP(connect_success); 415ATF_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 421ATF_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 444ATF_TC_CLEANUP(connect_success, tc) 445{ 446 cleanup(); 447} 448 449 450ATF_TC_WITH_CLEANUP(connect_failure); 451ATF_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 457ATF_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 470ATF_TC_CLEANUP(connect_failure, tc) 471{ 472 cleanup(); 473} 474 475 476ATF_TC_WITH_CLEANUP(connectat_success); 477ATF_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 483ATF_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 507ATF_TC_CLEANUP(connectat_success, tc) 508{ 509 cleanup(); 510} 511 512 513ATF_TC_WITH_CLEANUP(connectat_failure); 514ATF_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 520ATF_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 532ATF_TC_CLEANUP(connectat_failure, tc) 533{ 534 cleanup(); 535} 536 537 538ATF_TC_WITH_CLEANUP(accept_success); 539ATF_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 545ATF_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 569ATF_TC_CLEANUP(accept_success, tc) 570{ 571 cleanup(); 572} 573 574 575ATF_TC_WITH_CLEANUP(accept_failure); 576ATF_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 582ATF_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 591ATF_TC_CLEANUP(accept_failure, tc) 592{ 593 cleanup(); 594} 595 596 597ATF_TC_WITH_CLEANUP(send_success); 598ATF_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 604ATF_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 631ATF_TC_CLEANUP(send_success, tc) 632{ 633 cleanup(); 634} 635 636 637ATF_TC_WITH_CLEANUP(send_failure); 638ATF_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 644ATF_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 653ATF_TC_CLEANUP(send_failure, tc) 654{ 655 cleanup(); 656} 657 658 659ATF_TC_WITH_CLEANUP(recv_success); 660ATF_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 666ATF_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 694ATF_TC_CLEANUP(recv_success, tc) 695{ 696 cleanup(); 697} 698 699 700ATF_TC_WITH_CLEANUP(recv_failure); 701ATF_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 707ATF_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 716ATF_TC_CLEANUP(recv_failure, tc) 717{ 718 cleanup(); 719} 720 721 722ATF_TC_WITH_CLEANUP(sendto_success); 723ATF_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 729ATF_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 753ATF_TC_CLEANUP(sendto_success, tc) 754{ 755 cleanup(); 756} 757 758 759ATF_TC_WITH_CLEANUP(sendto_failure); 760ATF_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 766ATF_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 775ATF_TC_CLEANUP(sendto_failure, tc) 776{ 777 cleanup(); 778} 779 780 781ATF_TC_WITH_CLEANUP(recvfrom_success); 782ATF_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 788ATF_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 814ATF_TC_CLEANUP(recvfrom_success, tc) 815{ 816 cleanup(); 817} 818 819 820ATF_TC_WITH_CLEANUP(recvfrom_failure); 821ATF_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 827ATF_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 836ATF_TC_CLEANUP(recvfrom_failure, tc) 837{ 838 cleanup(); 839} 840 841 842ATF_TC_WITH_CLEANUP(sendmsg_success); 843ATF_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 849ATF_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 876ATF_TC_CLEANUP(sendmsg_success, tc) 877{ 878 cleanup(); 879} 880 881 882ATF_TC_WITH_CLEANUP(sendmsg_failure); 883ATF_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 889ATF_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 898ATF_TC_CLEANUP(sendmsg_failure, tc) 899{ 900 cleanup(); 901} 902 903 904ATF_TC_WITH_CLEANUP(recvmsg_success); 905ATF_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 911ATF_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 944ATF_TC_CLEANUP(recvmsg_success, tc) 945{ 946 cleanup(); 947} 948 949 950ATF_TC_WITH_CLEANUP(recvmsg_failure); 951ATF_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 957ATF_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 966ATF_TC_CLEANUP(recvmsg_failure, tc) 967{ 968 cleanup(); 969} 970 971 972ATF_TC_WITH_CLEANUP(shutdown_success); 973ATF_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 979ATF_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 1004ATF_TC_CLEANUP(shutdown_success, tc) 1005{ 1006 cleanup(); 1007} 1008 1009 1010ATF_TC_WITH_CLEANUP(shutdown_failure); 1011ATF_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 1017ATF_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 1029ATF_TC_CLEANUP(shutdown_failure, tc) 1030{ 1031 cleanup(); 1032} 1033 1034 1035ATF_TC_WITH_CLEANUP(sendfile_success); 1036ATF_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 1042ATF_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 1060ATF_TC_CLEANUP(sendfile_success, tc) 1061{ 1062 cleanup(); 1063} 1064 1065 1066ATF_TC_WITH_CLEANUP(sendfile_failure); 1067ATF_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 1073ATF_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 1083ATF_TC_CLEANUP(sendfile_failure, tc) 1084{ 1085 cleanup(); 1086} 1087 1088 1089ATF_TC_WITH_CLEANUP(setfib_success); 1090ATF_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 1096ATF_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 1106ATF_TC_CLEANUP(setfib_success, tc) 1107{ 1108 cleanup(); 1109} 1110 1111 1112ATF_TC_WITH_CLEANUP(setfib_failure); 1113ATF_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 1119ATF_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 1129ATF_TC_CLEANUP(setfib_failure, tc) 1130{ 1131 cleanup(); 1132} 1133 1134 1135ATF_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