Blame SOURCES/pam-1.3.1-fds-closing.patch

43d219
diff -up Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c.fds-closing Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c
43d219
--- Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c.fds-closing	2017-02-10 11:10:15.000000000 +0100
43d219
+++ Linux-PAM-1.3.1/libpam/pam_modutil_sanitize.c	2019-10-16 16:07:31.259021159 +0200
43d219
@@ -10,6 +10,7 @@
43d219
 #include <fcntl.h>
43d219
 #include <syslog.h>
43d219
 #include <sys/resource.h>
43d219
+#include <dirent.h>
43d219
 
43d219
 /*
43d219
  * Creates a pipe, closes its write end, redirects fd to its read end.
43d219
@@ -116,27 +117,45 @@ redirect_out(pam_handle_t *pamh, enum pa
43d219
 static void
43d219
 close_fds(void)
43d219
 {
43d219
+	DIR *dir = NULL;
43d219
+	struct dirent *dent;
43d219
+	int dfd = -1;
43d219
+	int fd;
43d219
+	struct rlimit rlim;
43d219
+
43d219
 	/*
43d219
 	 * An arbitrary upper limit for the maximum file descriptor number
43d219
 	 * returned by RLIMIT_NOFILE.
43d219
 	 */
43d219
-	const int MAX_FD_NO = 65535;
43d219
+	const unsigned int MAX_FD_NO = 65535;
43d219
 
43d219
 	/* The lower limit is the same as for _POSIX_OPEN_MAX. */
43d219
-	const int MIN_FD_NO = 20;
43d219
+	const unsigned int MIN_FD_NO = 20;
43d219
 
43d219
-	int fd;
43d219
-	struct rlimit rlim;
43d219
-
43d219
-	if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO)
43d219
-		fd = MAX_FD_NO;
43d219
-	else if (rlim.rlim_max < MIN_FD_NO)
43d219
-		fd = MIN_FD_NO;
43d219
-	else
43d219
-		fd = rlim.rlim_max - 1;
43d219
+	/* If /proc is mounted, we can optimize which fd can be closed. */
43d219
+	if ((dir = opendir("/proc/self/fd")) != NULL) {
43d219
+		if ((dfd = dirfd(dir)) >= 0) {
43d219
+			while ((dent = readdir(dir)) != NULL) {
43d219
+				fd = atoi(dent->d_name);
43d219
+				if (fd > STDERR_FILENO && fd != dfd)
43d219
+					close(fd);
43d219
+			}
43d219
+		}
43d219
+		closedir(dir);
43d219
+	}
43d219
+
43d219
+	/* If /proc isn't available, fallback to the previous behavior. */
43d219
+	if (dfd < 0) {
43d219
+		if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO)
43d219
+			fd = MAX_FD_NO;
43d219
+		else if (rlim.rlim_max < MIN_FD_NO)
43d219
+			fd = MIN_FD_NO;
43d219
+		else
43d219
+			fd = rlim.rlim_max - 1;
43d219
 
43d219
-	for (; fd > STDERR_FILENO; --fd)
43d219
-		close(fd);
43d219
+		for (; fd > STDERR_FILENO; --fd)
43d219
+			close(fd);
43d219
+	}
43d219
 }
43d219
 
43d219
 int