Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 26 May 2018 23:14:09 GMT
From:      aniketp@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r337254 - soc2018/aniketp/head/tests/sys/audit
Message-ID:  <201805262314.w4QNE9qn067546@socsvn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: aniketp
Date: Sat May 26 23:14:07 2018
New Revision: 337254
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337254

Log:
  Complete all test cases for 'network' audit class
  

Modified:
  soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c
  soc2018/aniketp/head/tests/sys/audit/network.c

Modified: soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c
==============================================================================
--- soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c	Sat May 26 01:31:51 2018	(r337253)
+++ soc2018/aniketp/head/tests/sys/audit/file-attribute-access.c	Sat May 26 23:14:07 2018	(r337254)
@@ -43,7 +43,6 @@
 #include "utils.h"
 
 static struct pollfd fds[1];
-
 static fhandle_t fht;
 static mode_t mode = 0777;
 static char extregex[80];
@@ -373,6 +372,108 @@
 }
 
 
+ATF_TC_WITH_CLEANUP(getfh_success);
+ATF_TC_HEAD(getfh_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"getfh(2) call");
+}
+
+ATF_TC_BODY(getfh_success, tc)
+{
+	atf_tc_expect_fail("getfh(2) is audited as nfs_getfh(2) in 'ad'"
+				"audit class in success mode");
+
+	/* File needs to exist to get a file-handle */
+	ATF_REQUIRE(open(path, O_CREAT, mode) != -1);
+	const char *regex = "getfh.*return,success";
+	FILE *pipefd = setup(fds, "fa");
+	ATF_REQUIRE_EQ(0, getfh(path, &fht));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(getfh_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(getfh_failure);
+ATF_TC_HEAD(getfh_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"getfh(2) call");
+}
+
+ATF_TC_BODY(getfh_failure, tc)
+{
+	atf_tc_expect_fail("getfh(2) is audited as nfs_getfh(2) in 'ad'"
+				"audit class in failure mode");
+
+	const char *regex = "getfh.*return,failure";
+	FILE *pipefd = setup(fds, "fa");
+	/* Failure reason: file does not exist */
+	ATF_REQUIRE_EQ(0, lgetfh(errpath, &fht));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(getfh_failure, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(lgetfh_success);
+ATF_TC_HEAD(lgetfh_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"lgetfh(2) call");
+}
+
+ATF_TC_BODY(lgetfh_success, tc)
+{
+	/* BSM conversion requested for unknown event 43061 */
+	atf_tc_expect_fail("lgetfh(2) does not get audited in success mode");
+
+	/* Symbolic link needs to exist to get a file-handle */
+	ATF_REQUIRE_EQ(0, symlink("symlink", path));
+	const char *regex = "lgetfh.*return,success";
+	FILE *pipefd = setup(fds, "fa");
+	ATF_REQUIRE_EQ(0, lgetfh(path, &fht));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(lgetfh_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(lgetfh_failure);
+ATF_TC_HEAD(lgetfh_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"lgetfh(2) call");
+}
+
+ATF_TC_BODY(lgetfh_failure, tc)
+{
+	/* BSM conversion requested for unknown event 43061 */
+	atf_tc_expect_fail("lgetfh(2) does not get audited in failure mode");
+
+	const char *regex = "lgetfh.*return,failure";
+	FILE *pipefd = setup(fds, "fa");
+	/* Failure reason: symbolic link does not exist */
+	ATF_REQUIRE_EQ(0, lgetfh(errpath, &fht));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(lgetfh_failure, tc)
+{
+	cleanup();
+}
+
+
 ATF_TC_WITH_CLEANUP(fhopen_success);
 ATF_TC_HEAD(fhopen_success, tc)
 {
@@ -1901,6 +2002,11 @@
 	ATF_TP_ADD_TC(tp, getfsstat_success);
 	ATF_TP_ADD_TC(tp, getfsstat_failure);
 
+	ATF_TP_ADD_TC(tp, getfh_success);
+	ATF_TP_ADD_TC(tp, getfh_failure);
+	ATF_TP_ADD_TC(tp, lgetfh_success);
+	ATF_TP_ADD_TC(tp, lgetfh_failure);
+
 	ATF_TP_ADD_TC(tp, fhopen_success);
 	ATF_TP_ADD_TC(tp, fhopen_failure);
 	ATF_TP_ADD_TC(tp, fhstat_success);

Modified: soc2018/aniketp/head/tests/sys/audit/network.c
==============================================================================
--- soc2018/aniketp/head/tests/sys/audit/network.c	Sat May 26 01:31:51 2018	(r337253)
+++ soc2018/aniketp/head/tests/sys/audit/network.c	Sat May 26 23:14:07 2018	(r337254)
@@ -27,7 +27,11 @@
  */
 
 #include <sys/types.h>
+#include <sys/select.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/uio.h>
 #include <sys/un.h>
 
 #include <netinet/in.h>
@@ -35,17 +39,24 @@
 
 #include <atf-c.h>
 #include <fcntl.h>
+#include <stdarg.h>
 #include <unistd.h>
 
 #include "utils.h"
+
 #define ERROR (-1)
 #define SERVER_PATH "server"
+#define MAX_DATA 1024
 
+static struct pollfd fds[1];
 static int sockfd, sockfd2;
 static int tr = 1;
 static socklen_t len;
-static struct pollfd fds[1];
-static char regex[40];
+static mode_t mode = 0777;
+static char regex[60];
+static char data[MAX_DATA];
+static char msgbuff[] = "Sample Message";
+static const char *path = "fileforaudit";
 
 /*
  * Assign local address to a server's socket
@@ -58,6 +69,65 @@
 	strcpy(server->sun_path, SERVER_PATH);
 }
 
+/*
+ * Check the read status of client socket descriptor
+ */
+static int
+check_readfs(int clientfd)
+{
+	struct timeval timeout;
+	timeout.tv_sec = 5;
+	timeout.tv_usec = 0;
+
+	/* Initialize fd_set using the provided MACROS for select() */
+	fd_set readfs;
+	FD_ZERO(&readfs);
+ 	FD_SET(clientfd, &readfs);
+
+	/* Check if clientfd is ready for receiving data and return */
+	ATF_REQUIRE(select(clientfd+1, &readfs, NULL, NULL, &timeout) > 0);
+	return (FD_ISSET(clientfd, &readfs));
+}
+
+/*
+ * Initialize iovec structure to be used as a field of struct msghdr
+ */
+static void
+init_iov(struct iovec *io, char msgbuf[], int DATALEN)
+{
+	io->iov_base = msgbuf;
+	io->iov_len = DATALEN;
+}
+
+/*
+ * Initialize msghdr structure for communication via datagram sockets
+ */
+static void
+init_msghdr(struct msghdr *hdrbuf, struct iovec *io, struct sockaddr_un *address)
+{
+	ssize_t length;
+	length = sizeof(struct sockaddr_un);
+	hdrbuf->msg_name = address;
+	hdrbuf->msg_namelen = length;
+	hdrbuf->msg_iov = io;
+	hdrbuf->msg_iovlen = 1;
+}
+
+/*
+ * Variadic function to close socket descriptors
+ */
+static void
+close_sockets(int count, ...)
+{
+	int sockd;
+	va_list socklist;
+	va_start(socklist, count);
+	for (sockd = 0; sockd < count; sockd++) {
+		close(va_arg(socklist, int));
+	}
+	va_end(socklist);
+}
+
 
 ATF_TC_WITH_CLEANUP(socket_success);
 ATF_TC_HEAD(socket_success, tc)
@@ -71,7 +141,7 @@
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 	/* Check the presence of sockfd in audit record */
-	snprintf(regex, 30, "socket.*return,success,%d", sockfd);
+	snprintf(regex, 60, "socket.*return,success,%d", sockfd);
 	check_audit(fds, regex, pipefd);
 	close(sockfd);
 }
@@ -94,7 +164,7 @@
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, socket(ERROR, SOCK_STREAM, 0));
 	/* Check the presence of hex(-1) in audit record */
-	snprintf(regex, 40, "socket.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "socket.*0x%x.*return,failure", ERROR);
 	check_audit(fds, regex, pipefd);
 }
 
@@ -117,12 +187,10 @@
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, socketpair(PF_UNIX, SOCK_STREAM, 0, sv));
 	/* Check the presence of 0x0 in audit record */
-	snprintf(regex, 40, "socketpair.*0x0.*return,success");
+	snprintf(regex, 60, "socketpair.*0x0.*return,success");
 	check_audit(fds, regex, pipefd);
-
 	/* Close all socket descriptors */
-	close(sv[0]);
-	close(sv[1]);
+	close_sockets(2, sv[0], sv[1]);
 }
 
 ATF_TC_CLEANUP(socketpair_success, tc)
@@ -144,7 +212,7 @@
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, socketpair(ERROR, SOCK_STREAM, 0, &sv));
 	/* Check the presence of hex(-1) in audit record */
-	snprintf(regex, 40, "socketpair.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "socketpair.*0x%x.*return,failure", ERROR);
 	check_audit(fds, regex, pipefd);
 }
 
@@ -165,7 +233,7 @@
 {
 	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 	/* Check the presence of sockfd in audit record */
-	snprintf(regex, 30, "setsockopt.*0x%x.*return,success", sockfd);
+	snprintf(regex, 60, "setsockopt.*0x%x.*return,success", sockfd);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &tr, \
@@ -193,7 +261,7 @@
 	ATF_REQUIRE_EQ(-1, setsockopt(ERROR, SOL_SOCKET, SO_REUSEADDR, &tr, \
 		sizeof(int)));
 	/* Check the presence of hex(-1) in audit record */
-	snprintf(regex, 40, "setsockopt.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "setsockopt.*0x%x.*return,failure", ERROR);
 	check_audit(fds, regex, pipefd);
 }
 
@@ -219,7 +287,7 @@
 	/* Preliminary socket setup */
 	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 	/* Check the presence of AF_UNIX address path in audit record */
-	snprintf(regex, 30, "bind.*unix.*%s.*return,success", SERVER_PATH);
+	snprintf(regex, 60, "bind.*unix.*%s.*return,success", SERVER_PATH);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
@@ -250,7 +318,7 @@
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, bind(-1, (struct sockaddr *)&server, len));
 	/* Check the presence of hex(-1) and AF_UNIX path in audit record */
-	snprintf(regex, 40, "bind.*0x%x.*%s.*return,failure", ERROR, SERVER_PATH);
+	snprintf(regex, 60, "bind.*0x%x.*%s.*return,failure", ERROR, SERVER_PATH);
 	check_audit(fds, regex, pipefd);
 }
 
@@ -276,7 +344,7 @@
 	/* Preliminary socket setup */
 	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 	/* Check the presence of socket descriptor in audit record */
-	snprintf(regex, 30, "bindat.*0x%x.*return,success", sockfd);
+	snprintf(regex, 60, "bindat.*0x%x.*return,success", sockfd);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, bindat(AT_FDCWD, sockfd, \
@@ -308,7 +376,7 @@
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, bindat(AT_FDCWD, -1, (struct sockaddr *)&server, len));
 	/* Check the presence of hex(-1) in audit record */
-	snprintf(regex, 40, "bindat.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "bindat.*0x%x.*return,failure", ERROR);
 	check_audit(fds, regex, pipefd);
 }
 
@@ -335,7 +403,7 @@
 	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
 	/* Check the presence of socket descriptor in the audit record */
-	snprintf(regex, 30, "listen.*0x%x.*return,success", sockfd);
+	snprintf(regex, 60, "listen.*0x%x.*return,success", sockfd);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
@@ -361,7 +429,7 @@
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, listen(ERROR, 1));
 	/* Check the presence of hex(-1) in audit record */
-	snprintf(regex, 40, "listen.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "listen.*0x%x.*return,failure", ERROR);
 	check_audit(fds, regex, pipefd);
 }
 
@@ -396,15 +464,14 @@
 	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 
 	/* Audit record must contain AF_UNIX address path & sockfd2 */
-	snprintf(regex, 40, "connect.*0x%x.*%s.*success", sockfd2, SERVER_PATH);
+	snprintf(regex, 60, "connect.*0x%x.*%s.*success", sockfd2, SERVER_PATH);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
 	check_audit(fds, regex, pipefd);
 
 	/* Close all socket descriptors */
-	close(sockfd);
-	close(sockfd2);
+	close_sockets(2, sockfd, sockfd2);
 }
 
 ATF_TC_CLEANUP(connect_success, tc)
@@ -428,7 +495,7 @@
 	len = sizeof(struct sockaddr_un);
 
 	/* Audit record must contain AF_UNIX address path & Hex(-1) */
-	snprintf(regex, 40, "connect.*0x%x.*%s.*failure", ERROR, SERVER_PATH);
+	snprintf(regex, 60, "connect.*0x%x.*%s.*failure", ERROR, SERVER_PATH);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, connect(ERROR, (struct sockaddr *)&server, len));
@@ -466,7 +533,7 @@
 	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 
 	/* Audit record must contain sockfd2 */
-	snprintf(regex, 30, "connectat.*0x%x.*return,success", sockfd2);
+	snprintf(regex, 60, "connectat.*0x%x.*return,success", sockfd2);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, connectat(AT_FDCWD, sockfd2, \
@@ -474,8 +541,7 @@
 	check_audit(fds, regex, pipefd);
 
 	/* Close all socket descriptors */
-	close(sockfd);
-	close(sockfd2);
+	close_sockets(2, sockfd, sockfd2);
 }
 
 ATF_TC_CLEANUP(connectat_success, tc)
@@ -499,7 +565,7 @@
 	len = sizeof(struct sockaddr_un);
 
 	/* Audit record must contain Hex(-1) */
-	snprintf(regex, 30, "connectat.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "connectat.*0x%x.*return,failure", ERROR);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, connectat(AT_FDCWD, ERROR, \
@@ -543,15 +609,13 @@
 	ATF_REQUIRE((clientfd = accept(sockfd, \
 		(struct sockaddr *)&client, &len)) != -1);
 
-	/* Audit record must contain clientfd & sockfd2 */
-	snprintf(regex, 40, \
+	/* Audit record must contain clientfd & sockfd */
+	snprintf(regex, 60, \
 		"accept.*0x%x.*return,success,%d", sockfd, clientfd);
 	check_audit(fds, regex, pipefd);
 
 	/* Close all socket descriptors */
-	close(sockfd);
-	close(sockfd2);
-	close(clientfd);
+	close_sockets(3, sockfd, sockfd2, clientfd);
 }
 
 ATF_TC_CLEANUP(accept_success, tc)
@@ -574,7 +638,7 @@
 	len = sizeof(struct sockaddr_un);
 
 	/* Audit record must contain Hex(-1) */
-	snprintf(regex, 30, "accept.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "accept.*0x%x.*return,failure", ERROR);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, accept(ERROR, (struct sockaddr *)&client, &len));
@@ -587,6 +651,465 @@
 }
 
 
+ATF_TC_WITH_CLEANUP(send_success);
+ATF_TC_HEAD(send_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"send(2) call");
+}
+
+ATF_TC_BODY(send_success, tc)
+{
+	/* Preliminary socket setup */
+	int clientfd;
+	ssize_t bytes_sent;
+	struct sockaddr_un server, client;
+	assign_address(&server);
+	len = sizeof(struct sockaddr_un);
+
+	/* Server Socket: Assign address and listen for connection */
+	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	/* Non-blocking server socket */
+	ATF_REQUIRE(fcntl(sockfd, F_SETFL, O_NONBLOCK) != -1);
+	/* Bind to the specified address and wait for connection */
+	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
+	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
+
+	/* Set up "blocking" client and connect with non-blocking server */
+	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
+	ATF_REQUIRE((clientfd = accept(sockfd, \
+		(struct sockaddr *)&client, &len)) != -1);
+
+	/* Send a sample message to the connected socket */
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE((bytes_sent = \
+		send(sockfd2, msgbuff, strlen(msgbuff), 0)) != -1);
+
+	/* Audit record must contain sockfd2 and bytes_sent */
+	snprintf(regex, 60, \
+		"send.*0x%x.*return,success,%zd", sockfd2, bytes_sent);
+	check_audit(fds, regex, pipefd);
+
+	/* Close all socket descriptors */
+	close_sockets(3, sockfd, sockfd2, clientfd);
+}
+
+ATF_TC_CLEANUP(send_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(send_failure);
+ATF_TC_HEAD(send_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"send(2) call");
+}
+
+ATF_TC_BODY(send_failure, tc)
+{
+	/* Audit record must contain Hex(-1) */
+	snprintf(regex, 60, "send.*0x%x.*return,failure", ERROR);
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(-1, send(ERROR, msgbuff, strlen(msgbuff), 0));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(send_failure, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(recv_success);
+ATF_TC_HEAD(recv_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"recv(2) call");
+}
+
+ATF_TC_BODY(recv_success, tc)
+{
+	/* Preliminary socket setup */
+	int clientfd;
+	ssize_t bytes_recv;
+	struct sockaddr_un server, client;
+	assign_address(&server);
+	len = sizeof(struct sockaddr_un);
+
+	/* Server Socket: Assign address and listen for connection */
+	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	/* Non-blocking server socket */
+	ATF_REQUIRE(fcntl(sockfd, F_SETFL, O_NONBLOCK) != -1);
+	/* Bind to the specified address and wait for connection */
+	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
+	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
+
+	/* Set up "blocking" client and connect with non-blocking server */
+	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
+	ATF_REQUIRE((clientfd = accept(sockfd, \
+		(struct sockaddr *)&client, &len)) != -1);
+	/* Send a sample message to the connected socket */
+	ATF_REQUIRE(send(sockfd2, msgbuff, strlen(msgbuff), 0) != -1);
+
+	/* Receive data once clientfd is ready for reading */
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE(check_readfs(clientfd) != 0);
+	ATF_REQUIRE((bytes_recv = recv(clientfd, data, MAX_DATA, 0)) != 0);
+
+	/* Audit record must contain clientfd and bytes_recv */
+	snprintf(regex, 60, \
+		"recv.*0x%x.*return,success,%zd", clientfd, bytes_recv);
+	check_audit(fds, regex, pipefd);
+
+	/* Close all socket descriptors */
+	close_sockets(3, sockfd, sockfd2, clientfd);
+}
+
+ATF_TC_CLEANUP(recv_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(recv_failure);
+ATF_TC_HEAD(recv_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"recv(2) call");
+}
+
+ATF_TC_BODY(recv_failure, tc)
+{
+	/* Audit record must contain Hex(-1) */
+	snprintf(regex, 60, "recv.*0x%x.*return,failure", ERROR);
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(-1, recv(ERROR, data, MAX_DATA, 0));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(recv_failure, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(sendto_success);
+ATF_TC_HEAD(sendto_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"sendto(2) call");
+}
+
+ATF_TC_BODY(sendto_success, tc)
+{
+	/* Preliminary socket setup */
+	int clientfd;
+	ssize_t bytes_sent;
+	struct sockaddr_un server, client;
+	assign_address(&server);
+	len = sizeof(struct sockaddr_un);
+
+	/* Server Socket: Assign address and listen for connection */
+	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	/* Non-blocking server socket */
+	ATF_REQUIRE(fcntl(sockfd, F_SETFL, O_NONBLOCK) != -1);
+	/* Bind to the specified address and wait for connection */
+	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
+	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
+
+	/* Set up "blocking" client and connect with non-blocking server */
+	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
+	ATF_REQUIRE((clientfd = accept(sockfd, \
+		(struct sockaddr *)&client, &len)) != -1);
+
+	/* Send a sample message to client's address */
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE((bytes_sent = sendto(sockfd2, msgbuff, \
+		strlen(msgbuff), 0, (struct sockaddr *)&client, len)) != -1);
+
+	/* Audit record must contain  sockfd2 and bytes_sent */
+	snprintf(regex, 60, \
+		"sendto.*0x%x.*return,success,%zd", sockfd2, bytes_sent);
+	check_audit(fds, regex, pipefd);
+
+	/* Close all socket descriptors */
+	close_sockets(3, sockfd, sockfd2, clientfd);
+}
+
+ATF_TC_CLEANUP(sendto_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(sendto_failure);
+ATF_TC_HEAD(sendto_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"sendto(2) call");
+}
+
+ATF_TC_BODY(sendto_failure, tc)
+{
+	/* Preliminary client address setup */
+	struct sockaddr_un client;
+	len  = sizeof(struct sockaddr_un);
+
+	/* Audit record must contain Hex(-1) */
+	snprintf(regex, 60, "sendto.*0x%x.*return,failure", ERROR);
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(-1, sendto(ERROR, msgbuff, \
+		strlen(msgbuff), 0, (struct sockaddr *)&client, len));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(sendto_failure, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(recvfrom_success);
+ATF_TC_HEAD(recvfrom_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"recvfrom(2) call");
+}
+
+ATF_TC_BODY(recvfrom_success, tc)
+{
+	/* Preliminary socket setup */
+	int clientfd;
+	ssize_t bytes_recv;
+	struct sockaddr_un server, client;
+	assign_address(&server);
+	len = sizeof(struct sockaddr_un);
+
+	/* Server Socket: Assign address and listen for connection */
+	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	/* Non-blocking server socket */
+	ATF_REQUIRE(fcntl(sockfd, F_SETFL, O_NONBLOCK) != -1);
+	/* Bind to the specified address and wait for connection */
+	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
+	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
+
+	/* Set up "blocking" client and connect with non-blocking server */
+	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
+	ATF_REQUIRE((clientfd = accept(sockfd, \
+		(struct sockaddr *)&client, &len)) != -1);
+	/* Send a sample message to the connected socket */
+	ATF_REQUIRE(send(sockfd2, msgbuff, strlen(msgbuff), 0) != -1);
+
+	/* Receive data once clientfd is ready for reading */
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE(check_readfs(clientfd) != 0);
+	ATF_REQUIRE((bytes_recv = recvfrom(clientfd, data, \
+		MAX_DATA, 0, (struct sockaddr *)&client, &len)) != 0);
+
+	/* Audit record must contain clientfd and bytes_sent */
+	snprintf(regex, 60, \
+		"recvfrom.*0x%x.*return,success,%zd", clientfd, bytes_recv);
+	check_audit(fds, regex, pipefd);
+
+	/* Close all socket descriptors */
+	close_sockets(3, sockfd, sockfd2, clientfd);
+}
+
+ATF_TC_CLEANUP(recvfrom_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(recvfrom_failure);
+ATF_TC_HEAD(recvfrom_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"recvfrom(2) call");
+}
+
+ATF_TC_BODY(recvfrom_failure, tc)
+{
+	/* Preliminary client address setup */
+	struct sockaddr_un client;
+	len = sizeof(struct sockaddr_un);
+
+	/* Audit record must contain Hex(-1) */
+	snprintf(regex, 60, "recvfrom.*0x%x.*return,failure", ERROR);
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(-1, recvfrom(ERROR, data, \
+		MAX_DATA, 0, (struct sockaddr *)&client, &len));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(recvfrom_failure, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(sendmsg_success);
+ATF_TC_HEAD(sendmsg_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"recvmsg(2) call");
+}
+
+ATF_TC_BODY(sendmsg_success, tc)
+{
+	/* Preliminary socket setup */
+	ssize_t bytes_sent;
+	struct msghdr sendbuf = {}, recvbuf = {};
+	struct iovec io1, io2;
+	struct sockaddr_un server, client;
+	assign_address(&server);
+	len = sizeof(struct sockaddr_un);
+
+	/* Create a datagram server socket & bind to UNIX address family */
+	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
+	/* Non-blocking server socket */
+	ATF_REQUIRE(fcntl(sockfd, F_SETFL, O_NONBLOCK) != -1);
+	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
+
+	/* Message buffer to be sent to the server */
+	init_iov(&io1, msgbuff, sizeof(msgbuff));
+	init_msghdr(&sendbuf, &io1, &server);
+
+	/* Prepare buffer to store the received data in */
+	init_iov(&io2, data, MAX_DATA);
+	init_msghdr(&recvbuf, &io2, &client);
+
+	/* Set up "blocking" UDP client to communicate with the server */
+	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
+
+	/* Send a sample message to the specified client address */
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE((bytes_sent = sendmsg(sockfd2, &sendbuf, 0)) != -1);
+
+	/* Audit record must contain sockfd2 and bytes_sent */
+	snprintf(regex, 60, \
+		"sendmsg.*0x%x.*return,success,%zd", sockfd2, bytes_sent);
+	check_audit(fds, regex, pipefd);
+
+	/* Close all socket descriptors */
+	close_sockets(2, sockfd, sockfd2);
+}
+
+ATF_TC_CLEANUP(sendmsg_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(sendmsg_failure);
+ATF_TC_HEAD(sendmsg_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"sendmsg(2) call");
+}
+
+ATF_TC_BODY(sendmsg_failure, tc)
+{
+	struct msghdr msgbuf;
+	/* Audit record must contain Hex(-1) */
+	snprintf(regex, 60, "sendmsg.*return,failure : Message too long");
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(-1, sendmsg(ERROR, &msgbuf, 0));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(sendmsg_failure, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(recvmsg_success);
+ATF_TC_HEAD(recvmsg_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"recvmsg(2) call");
+}
+
+ATF_TC_BODY(recvmsg_success, tc)
+{
+	/* Preliminary socket setup */
+	ssize_t bytes_recv;
+	struct msghdr sendbuf = {}, recvbuf = {};
+	struct iovec io1, io2;
+	struct sockaddr_un server, client;
+	assign_address(&server);
+	len = sizeof(struct sockaddr_un);
+
+	/* Create a datagram server socket & bind to UNIX address family */
+	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
+	/* Non-blocking server socket */
+	ATF_REQUIRE(fcntl(sockfd, F_SETFL, O_NONBLOCK) != -1);
+	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
+
+	/* Message buffer to be sent to the server */
+	init_iov(&io1, msgbuff, sizeof(msgbuff));
+	init_msghdr(&sendbuf, &io1, &server);
+
+	/* Prepare buffer to store the received data in */
+	init_iov(&io2, data, MAX_DATA);
+	init_msghdr(&recvbuf, &io2, &client);
+
+	/* Set up "blocking" UDP client to communicate with the server */
+	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_DGRAM, 0)) != -1);
+	/* Send a sample message to the connected socket */
+	ATF_REQUIRE(sendmsg(sockfd2, &sendbuf, 0) != -1);
+
+	/* Receive data once clientfd is ready for reading */
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE(check_readfs(sockfd) != 0);
+	ATF_REQUIRE((bytes_recv = recvmsg(sockfd, &recvbuf, 0)) != -1);
+
+	/* Audit record must contain sockfd and bytes_recv */
+	snprintf(regex, 60, \
+		"recvmsg.*0x%x.*return,success,%zd", sockfd, bytes_recv);
+	check_audit(fds, regex, pipefd);
+
+	/* Close all socket descriptors */
+	close_sockets(2, sockfd, sockfd2);
+}
+
+ATF_TC_CLEANUP(recvmsg_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(recvmsg_failure);
+ATF_TC_HEAD(recvmsg_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"recvmsg(2) call");
+}
+
+ATF_TC_BODY(recvmsg_failure, tc)
+{
+	struct msghdr msgbuf;
+	/* Audit record must contain Hex(-1) */
+	snprintf(regex, 60, "recvmsg.*return,failure : Message too long");
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(-1, recvmsg(ERROR, &msgbuf, 0));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(recvmsg_failure, tc)
+{
+	cleanup();
+}
+
+
+
 ATF_TC_WITH_CLEANUP(shutdown_success);
 ATF_TC_HEAD(shutdown_success, tc)
 {
@@ -609,23 +1132,21 @@
 	ATF_REQUIRE_EQ(0, bind(sockfd, (struct sockaddr *)&server, len));
 	ATF_REQUIRE_EQ(0, listen(sockfd, 1));
 
-	/* Set up "blocking" client and connect with non-blocking server*/
+	/* Set up "blocking" client and connect with non-blocking server */
 	ATF_REQUIRE((sockfd2 = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
 	ATF_REQUIRE_EQ(0, connect(sockfd2, (struct sockaddr *)&server, len));
 	ATF_REQUIRE((clientfd = accept(sockfd, \
 		(struct sockaddr *)&client, &len)) != -1);
 
-	/* Audit record must contain clientfd & sockfd2 */
-	snprintf(regex, 40, "shutdown.*0x%x.*return,success", clientfd);
+	/* Audit record must contain clientfd */
+	snprintf(regex, 60, "shutdown.*0x%x.*return,success", clientfd);
 
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(0, shutdown(clientfd, SHUT_RDWR));
 	check_audit(fds, regex, pipefd);
 
 	/* Close all socket descriptors */
-	close(sockfd);
-	close(sockfd2);
-	close(clientfd);
+	close_sockets(3, sockfd, sockfd2, clientfd);
 }
 
 ATF_TC_CLEANUP(shutdown_success, tc)
@@ -644,7 +1165,7 @@
 ATF_TC_BODY(shutdown_failure, tc)
 {
 	/* Audit record must contain Hex(-1) */
-	snprintf(regex, 30, "shutdown.*0x%x.*return,failure", ERROR);
+	snprintf(regex, 60, "shutdown.*0x%x.*return,failure", ERROR);
 	FILE *pipefd = setup(fds, "nt");
 	ATF_REQUIRE_EQ(-1, shutdown(ERROR, SHUT_RDWR));
 	check_audit(fds, regex, pipefd);
@@ -656,6 +1177,104 @@
 }
 
 
+ATF_TC_WITH_CLEANUP(sendfile_success);
+ATF_TC_HEAD(sendfile_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"sendfile(2) call");
+}
+
+ATF_TC_BODY(sendfile_success, tc)
+{
+	int filedesc;
+	filedesc = open(path, O_CREAT | O_RDONLY, mode);
+	/* Create a simple UNIX socket to send out random data */
+	ATF_REQUIRE((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) != -1);
+	/* Check the presence of sockfd,non-file in the audit record */
+	snprintf(regex, 60, "sendfile.*0x%x,non-file.*return,success", filedesc);
+
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(0, sendfile(filedesc, sockfd, 0, 0, NULL, NULL, 0));
+	check_audit(fds, regex, pipefd);
+	close(sockfd);
+}
+
+ATF_TC_CLEANUP(sendfile_success, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(sendfile_failure);
+ATF_TC_HEAD(sendfile_failure, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of an unsuccessful "
+					"sendfile(2) call");
+}
+
+ATF_TC_BODY(sendfile_failure, tc)
+{
+	/* Audit record must contain Hex(-1) */
+	snprintf(regex, 60, "sendfile.*0x%x.*return,failure", ERROR);
+	FILE *pipefd = setup(fds, "nt");
+	ATF_REQUIRE_EQ(-1, sendfile(ERROR, ERROR, 0, 0, NULL, NULL, 0));
+	check_audit(fds, regex, pipefd);
+}
+
+ATF_TC_CLEANUP(sendfile_failure, tc)
+{
+	cleanup();
+}
+
+
+ATF_TC_WITH_CLEANUP(setfib_success);
+ATF_TC_HEAD(setfib_success, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Tests the audit of a successful "
+					"setfib(2) call");
+}
+
+ATF_TC_BODY(setfib_success, tc)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805262314.w4QNE9qn067546>