Blame SOURCES/fapolicyd-already-started.patch

1bfbac
diff -up ./src/daemon/fapolicyd.c.already-started ./src/daemon/fapolicyd.c
1bfbac
--- ./src/daemon/fapolicyd.c.already-started	2023-01-12 17:40:45.366909652 +0100
1bfbac
+++ ./src/daemon/fapolicyd.c	2023-01-12 17:46:22.458139519 +0100
1bfbac
@@ -378,6 +378,58 @@ static void usage(void)
1bfbac
 }
1bfbac
 
1bfbac
 
1bfbac
+int already_running(void)
1bfbac
+{
1bfbac
+	int pidfd = open(pidfile, O_RDONLY);
1bfbac
+	if (pidfd >= 0) {
1bfbac
+		char pid_buf[16];
1bfbac
+
1bfbac
+		if (fd_fgets(pid_buf, sizeof(pid_buf), pidfd)) {
1bfbac
+			int pid;
1bfbac
+			char exe_buf[80], my_path[80];
1bfbac
+
1bfbac
+			// Get our path
1bfbac
+			if (get_program_from_pid(getpid(),
1bfbac
+					sizeof(exe_buf), my_path) == NULL)
1bfbac
+				goto err_out; // shouldn't happen, but be safe
1bfbac
+
1bfbac
+			// convert pidfile to integer
1bfbac
+			errno = 0;
1bfbac
+			pid = strtoul(pid_buf, NULL, 10);
1bfbac
+			if (errno)
1bfbac
+				goto err_out; // shouldn't happen, but be safe
1bfbac
+
1bfbac
+			// verify it really is fapolicyd
1bfbac
+			if (get_program_from_pid(pid,
1bfbac
+					sizeof(exe_buf), exe_buf) == NULL)
1bfbac
+				goto good; //if pid doesn't exist, we're OK
1bfbac
+
1bfbac
+			// If the path doesn't have fapolicyd in it, we're OK
1bfbac
+			if (strstr(exe_buf, "fapolicyd") == NULL)
1bfbac
+				goto good;
1bfbac
+
1bfbac
+			if (strcmp(exe_buf, my_path) == 0)
1bfbac
+				goto err_out; // if the same, we need to exit
1bfbac
+
1bfbac
+			// one last sanity check in case path is unexpected
1bfbac
+			// for example: /sbin/fapolicyd & /home/test/fapolicyd
1bfbac
+			if (pid != getpid())
1bfbac
+				goto err_out;
1bfbac
+good:
1bfbac
+			close(pidfd);
1bfbac
+			unlink(pidfile);
1bfbac
+			return 0;
1bfbac
+		} else
1bfbac
+		    msg(LOG_ERR, "fapolicyd pid file found but unreadable");
1bfbac
+err_out: // At this point, we have a pid file, let's just assume it's alive
1bfbac
+	 // because if 2 are running, it deadlocks the machine
1bfbac
+		close(pidfd);
1bfbac
+		return 1;
1bfbac
+	}
1bfbac
+	return 0; // pid file doesn't exist, we're good to go
1bfbac
+}
1bfbac
+
1bfbac
+
1bfbac
 int main(int argc, const char *argv[])
1bfbac
 {
1bfbac
 	struct pollfd pfd[2];
1bfbac
@@ -428,6 +480,11 @@ int main(int argc, const char *argv[])
1bfbac
 		}
1bfbac
 	}
1bfbac
 
1bfbac
+	if (already_running()) {
1bfbac
+		msg(LOG_ERR, "fapolicyd is already running");
1bfbac
+		exit(1);
1bfbac
+	}
1bfbac
+
1bfbac
 	// Set a couple signal handlers
1bfbac
 	sa.sa_flags = 0;
1bfbac
 	sigemptyset(&sa.sa_mask);
1bfbac
@@ -446,9 +503,6 @@ int main(int argc, const char *argv[])
1bfbac
 	setrlimit(RLIMIT_FSIZE, &limit);
1bfbac
 	setrlimit(RLIMIT_NOFILE, &limit);
1bfbac
 
1bfbac
-	// Set strict umask
1bfbac
-	(void) umask( 0117 );
1bfbac
-
1bfbac
 	// get more time slices because everything is waiting on us
1bfbac
 	rc = nice(-config.nice_val);
1bfbac
 	if (rc == -1)
1bfbac
@@ -473,17 +527,20 @@ int main(int argc, const char *argv[])
1bfbac
 		exit(1);
1bfbac
 	}
1bfbac
 
1bfbac
-	if (preconstruct_fifo(&config)) {
1bfbac
-		msg(LOG_ERR, "Cannot contruct a pipe");
1bfbac
-		exit(1);
1bfbac
-	}
1bfbac
-
1bfbac
 	// Setup filesystem to watch list
1bfbac
 	init_fs_list(config.watch_fs);
1bfbac
 
1bfbac
 	// Write the pid file for the init system
1bfbac
 	write_pid_file();
1bfbac
 
1bfbac
+	// Set strict umask
1bfbac
+	(void) umask( 0117 );
1bfbac
+
1bfbac
+	if (preconstruct_fifo(&config)) {
1bfbac
+		msg(LOG_ERR, "Cannot contruct a pipe");
1bfbac
+		exit(1);
1bfbac
+	}
1bfbac
+
1bfbac
 	// If we are not going to be root, then setup necessary capabilities
1bfbac
 	if (config.uid != 0) {
1bfbac
 		capng_clear(CAPNG_SELECT_BOTH);