From 6d6c65e8e374ce31037e20b1cdc314808efd0e3c Mon Sep 17 00:00:00 2001
From: Steve Grubb <sgrubb@redhat.com>
Date: Sat, 24 Nov 2018 10:06:08 -0500
Subject: [PATCH] Port af_unix plugin to libev

---
 audisp/Makefile.am        |  3 ++-
 audisp/audispd-builtins.c | 42 +++++++++++++++++++++++++++++++--------
 audisp/audispd-builtins.h |  9 ++-------
 audisp/audispd.c          | 38 -----------------------------------
 src/auditd.c              | 18 ++++++++---------
 5 files changed, 47 insertions(+), 63 deletions(-)

diff --git a/audisp/Makefile.am b/audisp/Makefile.am
index 5aa1d09..852169e 100644
--- a/audisp/Makefile.am
+++ b/audisp/Makefile.am
@@ -22,7 +22,7 @@
 
 SUBDIRS = plugins 
 CONFIG_CLEAN_FILES = *.rej *.orig
-AM_CPPFLAGS = -D_GNU_SOURCE -fPIC -DPIC -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/src
+AM_CPPFLAGS = -D_GNU_SOURCE -fPIC -DPIC -I${top_srcdir} -I${top_srcdir}/lib -I${top_srcdir}/src -I${top_srcdir}/src/libev
 LIBS = -L${top_builddir}/lib -laudit 
 LDADD = -lpthread
 
@@ -30,5 +30,6 @@ noinst_HEADERS = audispd-pconfig.h audispd-llist.h audispd-config.h \
 	queue.h audispd-builtins.h libdisp.h
 libdisp_a_SOURCES = audispd.c audispd-pconfig.c queue.c \
 	audispd-llist.c audispd-builtins.c
+libdisp_a_CFLAGS = -fno-strict-aliasing
 noinst_LIBRARIES = libdisp.a
 
diff --git a/audisp/audispd-builtins.c b/audisp/audispd-builtins.c
index 1fbe680..024faec 100644
--- a/audisp/audispd-builtins.c
+++ b/audisp/audispd-builtins.c
@@ -1,6 +1,6 @@
 /*
 * audispd-builtins.c - some common builtin plugins
-* Copyright (c) 2007,2010,2013 Red Hat Inc., Durham, North Carolina.
+* Copyright (c) 2007,2010,2013,2018 Red Hat Inc., Durham, North Carolina.
 * All Rights Reserved. 
 *
 * This software may be freely redistributed and/or modified under the
@@ -35,12 +35,17 @@
 #include <sys/uio.h> // writev
 #include <fcntl.h>
 #include <stdio.h>
+#include "ev.h"
 #include "audispd-pconfig.h"
 #include "audispd-builtins.h"
 
+// Global data
+extern struct ev_loop *loop;
+
 // Local data
 static volatile int sock = -1, conn = -1;
 static char *path = NULL;
+static struct ev_io af_unix_watcher;
 
 // Local prototypes
 static void init_af_unix(const plugin_conf_t *conf);
@@ -63,21 +68,37 @@ void stop_builtin(plugin_conf_t *conf)
 		syslog(LOG_ERR, "Unknown builtin %s", conf->path);
 }
 
-static void af_unix_accept(int fd)
+static int watching = 0;
+static void stop_watching(void)
+{
+	if (watching) {
+		ev_io_stop(loop, &af_unix_watcher);
+		watching = 0;
+	}
+}
+
+static void af_unix_accept(struct ev_loop *l, struct ev_io *_io, int revents)
 {
 	int cmd;
 
 	do {
-		conn = accept(fd, NULL, NULL);
+		conn = accept(_io->fd, NULL, NULL);
 	} while (conn < 0 && errno == EINTR);
 
 	// De-register since this is intended to be one listener
 	if (conn >= 0)
-		remove_event(fd);
+		stop_watching();
 	cmd = fcntl(conn, F_GETFD);
 	fcntl(conn, F_SETFD, cmd|FD_CLOEXEC);
 }
 
+static void start_watching(void)
+{
+	ev_io_init(&af_unix_watcher, af_unix_accept, sock, EV_READ);
+	ev_io_start(loop, &af_unix_watcher);
+	watching = 1;
+}
+
 static int create_af_unix_socket(const char *path, int mode)
 {
 	struct sockaddr_un addr;
@@ -122,8 +143,8 @@ static int create_af_unix_socket(const char *path, int mode)
 	// Make socket listening...won't block
 	(void)listen(sock, 5);
 
-	// Register socket with poll
-	add_event(sock, af_unix_accept);
+	// Register socket with libev
+	start_watching();
 	return 0;
 }
 
@@ -213,7 +234,8 @@ void send_af_unix_string(const char *s, unsigned int len)
 		if (rc < 0 && errno == EPIPE) {
 			close(conn);
 			conn = -1;
-			add_event(sock, af_unix_accept);
+			stop_watching();
+			start_watching();
 		}
 	} 
 }
@@ -237,7 +259,8 @@ void send_af_unix_binary(event_t *e)
 		if (rc < 0 && errno == EPIPE) {
 			close(conn);
 			conn = -1;
-			add_event(sock, af_unix_accept);
+			stop_watching();
+			start_watching();
 		}
 	} 
 }
@@ -250,10 +273,13 @@ void destroy_af_unix(void)
 		conn = -1;
 		did_something = 1;
 	}
+	stop_watching();
 	if (sock >= 0) {
+
 		close(sock);
 		sock = -1;
 		did_something = 1;
+		
 	}
 	if (path) {
 		unlink(path);
diff --git a/audisp/audispd-builtins.h b/audisp/audispd-builtins.h
index 2083775..2d344ea 100644
--- a/audisp/audispd-builtins.h
+++ b/audisp/audispd-builtins.h
@@ -1,6 +1,6 @@
 /*
-* audispd-builtins.h - Minimal linked list library
-* Copyright (c) 2007,2013 Red Hat Inc., Durham, North Carolina.
+* audispd-builtins.h - Interface to builtin plugins
+* Copyright (c) 2007,2013,2018 Red Hat Inc., Durham, North Carolina.
 * All Rights Reserved. 
 *
 * This software may be freely redistributed and/or modified under the
@@ -33,10 +33,5 @@ void send_af_unix_string(const char *s, unsigned int len);
 void send_af_unix_binary(event_t *e);
 void destroy_af_unix(void);
 
-typedef void (*poll_callback_ptr)(int fd);
-int add_event(int fd, poll_callback_ptr cb);
-int remove_event(int fd);
-
-
 #endif
 
diff --git a/audisp/audispd.c b/audisp/audispd.c
index e9584b7..9c3a118 100644
--- a/audisp/audispd.c
+++ b/audisp/audispd.c
@@ -31,7 +31,6 @@
 #include <pthread.h>
 #include <dirent.h>
 #include <fcntl.h>
-#include <sys/poll.h>
 #include <netdb.h>
 #include <arpa/inet.h>
 #include <limits.h>
@@ -578,43 +577,6 @@ static int event_loop(void)
 		return 1;
 }
 
-static struct pollfd pfd[4];
-static poll_callback_ptr pfd_cb[4];
-static volatile int pfd_cnt=0;
-int add_event(int fd, poll_callback_ptr cb)
-{
-	if (pfd_cnt > 3)
-		return -1;
-
-	pfd[pfd_cnt].fd = fd;
-	pfd[pfd_cnt].events = POLLIN;
-	pfd[pfd_cnt].revents = 0;
-	pfd_cb[pfd_cnt] = cb;
-	pfd_cnt++;
-	return 0;
-}
-
-int remove_event(int fd)
-{
-	int start, i;
-	if (pfd_cnt == 0)
-		return -1;
-
-	for (start=0; start < pfd_cnt; start++) {
-		if (pfd[start].fd == fd)
-			break;
-	}
-	for (i=start; i<(pfd_cnt-1); i++) {
-		pfd[i].events = pfd[i+1].events;
-		pfd[i].revents = pfd[i+1].revents;
-		pfd[i].fd = pfd[i+1].fd;
-		pfd_cb[i] = pfd_cb[i+1];
-	}
-
-	pfd_cnt--;
-	return 0;
-}
-
 /* returns > 0 if plugins and 0 if none */
 int libdisp_active(void)
 {
diff --git a/src/auditd.c b/src/auditd.c
index bd7e3b8..22bdc9b 100644
--- a/src/auditd.c
+++ b/src/auditd.c
@@ -581,6 +581,7 @@ static void close_pipes(void)
 	close(pipefds[1]);
 }
 
+struct ev_loop *loop;
 int main(int argc, char *argv[])
 {
 	struct sigaction sa;
@@ -598,7 +599,6 @@ int main(int argc, char *argv[])
 	enum startup_state opt_startup = startup_enable;
 	extern char *optarg;
 	extern int optind;
-	struct ev_loop *loop;
 	struct ev_io netlink_watcher;
 	struct ev_io pipe_watcher;
 	struct ev_signal sigterm_watcher;
@@ -749,14 +749,6 @@ int main(int argc, char *argv[])
 		return 1;
 	}
 
-	if (init_dispatcher(&config)) {
-		if (pidfile)
-			unlink(pidfile);
-		tell_parent(FAILURE);
-		free_config(&config);
-		return 1;
-	}
-
 	/* Get machine name ready for use */
 	if (resolve_node(&config)) {
 		if (pidfile)
@@ -892,6 +884,14 @@ int main(int argc, char *argv[])
 	/* Depending on value of opt_startup (-s) set initial audit state */
 	loop = ev_default_loop (EVFLAG_NOENV);
 
+	if (init_dispatcher(&config)) {
+		if (pidfile)
+			unlink(pidfile);
+		tell_parent(FAILURE);
+		free_config(&config);
+		return 1;
+	}
+
 	if (!opt_aggregate_only) {
 		ev_io_init (&netlink_watcher, netlink_handler, fd, EV_READ);
 		ev_io_start (loop, &netlink_watcher);
