xref: /freebsd/tests/sys/audit/network.c (revision 069ac184)
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