From 2663987c5088924bce510fcf8e7891d6aae976ba Mon Sep 17 00:00:00 2001
From: cgzones <cgzones@googlemail.com>
Date: Sat, 4 Nov 2023 03:48:39 +0100
Subject: [PATCH] Avoid file descriptor leaks in multi-threaded applications
 (#339)

* lib: set close-on-exec flag

libaudit may be called from a multi-threaded application.
Avoid leaking local file descriptors on a concurrent execve.

* lib: simplify SOCK_CLOEXEC

SOCK_CLOEXEC is supported since Linux 2.6.27.

Reference:https://github.com/linux-audit/audit-userspace/commit/2663987c5088924bce510fcf8e7891d6aae976ba
Conflict:lib/audit_logging.c,lib/netlink.c,lib/libaudit.c

---
 lib/audit_logging.c |  2 +-
 lib/libaudit.c      | 14 +++++++-------
 lib/netlink.c       | 12 +-----------
 3 files changed, 9 insertions(+), 19 deletions(-)

diff --git a/lib/audit_logging.c b/lib/audit_logging.c
index 302c242..08b53aa 100644
--- a/lib/audit_logging.c
+++ b/lib/audit_logging.c
@@ -177,7 +177,7 @@ static char *_get_commname(const char *comm, char *commname, unsigned int size)
 	
 	if (comm == NULL) {
 		int len;
-		int fd = open("/proc/self/comm", O_RDONLY);
+		int fd = open("/proc/self/comm", O_RDONLY|O_CLOEXEC);
 		if (fd < 0) {
 			strcpy(commname, "\"?\"");
 			return commname;
diff --git a/lib/libaudit.c b/lib/libaudit.c
index 2cc7afd..74fa2f3 100644
--- a/lib/libaudit.c
+++ b/lib/libaudit.c
@@ -221,7 +221,7 @@ static int load_libaudit_config(const char *path)
 	char buf[128];
 
 	/* open the file */
-	rc = open(path, O_NOFOLLOW|O_RDONLY);
+	rc = open(path, O_NOFOLLOW|O_RDONLY|O_CLOEXEC);
 	if (rc < 0) {
 		if (errno != ENOENT) {
 			audit_msg(LOG_ERR, "Error opening %s (%s)",
@@ -261,7 +261,7 @@ static int load_libaudit_config(const char *path)
 	}
 
 	/* it's ok, read line by line */
-	f = fdopen(fd, "rm");
+	f = fdopen(fd, "rme");
 	if (f == NULL) {
 		audit_msg(LOG_ERR, "Error - fdopen failed (%s)",
 			strerror(errno));
@@ -705,7 +705,7 @@ char *audit_format_signal_info(char *buf, int len, char *op,
 	char path[32], ses[16];
 	int rlen;
 	snprintf(path, sizeof(path), "/proc/%u", rep->signal_info->pid);
-	int fd = open(path, O_RDONLY);
+	int fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
 	if (fd >= 0) {
 		if (fstat(fd, &sb) < 0)
 			sb.st_uid = -1;
@@ -714,7 +714,7 @@ char *audit_format_signal_info(char *buf, int len, char *op,
 		sb.st_uid = -1;
 	snprintf(path, sizeof(path), "/proc/%u/sessionid",
 		 rep->signal_info->pid);
-	fd = open(path, O_RDONLY, rep->signal_info->pid);
+	fd = open(path, O_RDONLY|O_CLOEXEC, rep->signal_info->pid);
 	if (fd < 0)
 		strcpy(ses, "4294967295");
 	else {
@@ -918,7 +918,7 @@ uid_t audit_getloginuid(void)
 	char buf[16];
 
 	errno = 0;
-	in = open("/proc/self/loginuid", O_NOFOLLOW|O_RDONLY);
+	in = open("/proc/self/loginuid", O_NOFOLLOW|O_RDONLY|O_CLOEXEC);
 	if (in < 0)
 		return -1;
 	do {
@@ -946,7 +946,7 @@ int audit_setloginuid(uid_t uid)
 
 	errno = 0;
 	count = snprintf(loginuid, sizeof(loginuid), "%u", uid);
-	o = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC);
+	o = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC|O_CLOEXEC);
 	if (o >= 0) {
 		int block, offset = 0;
 
@@ -982,7 +982,7 @@ uint32_t audit_get_session(void)
 	char buf[16];
 
 	errno = 0;
-	in = open("/proc/self/sessionid", O_NOFOLLOW|O_RDONLY);
+	in = open("/proc/self/sessionid", O_NOFOLLOW|O_RDONLY|O_CLOEXEC);
 	if (in < 0)
 		return -2;
 	do {
diff --git a/lib/netlink.c b/lib/netlink.c
index 66a1e7c..f862da4 100644
--- a/lib/netlink.c
+++ b/lib/netlink.c
@@ -47,7 +47,7 @@ static int check_ack(int fd);
 int audit_open(void)
 {
 	int saved_errno;
-	int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
+	int fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT);
 
 	if (fd < 0) {
 		saved_errno = errno;
@@ -60,16 +60,6 @@ int audit_open(void)
 				"Error opening audit netlink socket (%s)", 
 				strerror(errno));
 		errno = saved_errno;
-		return fd;
-	}
-	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) {
-		saved_errno = errno;
-		audit_msg(LOG_ERR, 
-			"Error setting audit netlink socket CLOEXEC flag (%s)", 
-			strerror(errno));
-		close(fd);
-		errno = saved_errno;
-		return -1;
 	}
 	return fd;
 }
-- 
2.33.0

