From d6103b30050554d7b6ca6d55cb5b4ed3c9516663 Mon Sep 17 00:00:00 2001
From: Iker Pedrosa <ipedrosa@redhat.com>
Date: Wed, 25 Oct 2023 09:46:15 +0200
Subject: [PATCH] libpam: use close_range() to close file descriptors

* configure.ac: check whether close_range() is available in the system.
* libpam/pam_modutil_sanitize.c: use close_range() to close all file
  descriptors. If the interface isn't available use the previous
  approach.

Link: https://github.com/linux-pam/linux-pam/pull/276
Resolves: https://issues.redhat.com/browse/RHEL-5099

Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>

Conflict:NA
Reference:https://github.com/linux-pam/linux-pam/commit/d6103b30050554d7b6ca6d55cb5b4ed3c9516663

---
 configure.ac                  |  1 +
 libpam/pam_modutil_sanitize.c | 19 +++++++++++++++++--
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index 39124d87..b6a8d6fb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -638,6 +638,7 @@ AC_CHECK_FUNCS(quotactl)
 AC_CHECK_FUNCS(unshare)
 AC_CHECK_FUNCS(explicit_bzero memset_explicit)
 AC_CHECK_FUNCS([ruserok_af ruserok], [break])
+AC_CHECK_FUNCS(close_range)
 
 AC_ARG_ENABLE([regenerate-docu],
   AS_HELP_STRING([--disable-regenerate-docu],[Don't re-build documentation from XML sources]),
diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c
index f26e8ec0..1b8af743 100644
--- a/libpam/pam_modutil_sanitize.c
+++ b/libpam/pam_modutil_sanitize.c
@@ -11,6 +11,10 @@
 #include <syslog.h>
 #include <sys/resource.h>
 
+#ifndef CLOSE_RANGE_UNSHARE
+#define CLOSE_RANGE_UNSHARE	(1U << 1)
+#endif /* CLOSE_RANGE_UNSHARE */
+
 /*
  * Creates a pipe, closes its write end, redirects fd to its read end.
  * Returns fd on success, -1 otherwise.
@@ -84,9 +88,8 @@ redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode,
 	return fd;
 }
 
-/* Closes all descriptors after stderr. */
 static void
-close_fds(void)
+close_fds_iteratively(void)
 {
 	/*
 	 * An arbitrary upper limit for the maximum file descriptor number
@@ -111,6 +114,18 @@ close_fds(void)
 		close(fd);
 }
 
+/* Closes all descriptors after stderr. */
+static void
+close_fds(void)
+{
+#ifdef HAVE_CLOSE_RANGE
+	if (close_range(STDERR_FILENO+1, -1U, CLOSE_RANGE_UNSHARE) == 0)
+		return;
+#endif /* HAVE_CLOSE_RANGE */
+
+	close_fds_iteratively();
+}
+
 int
 pam_modutil_sanitize_helper_fds(pam_handle_t *pamh,
 				enum pam_modutil_redirect_fd stdin_mode,
-- 
2.33.0

