Blame SOURCES/pam-1.5.1-pam-limits-unlimited-value.patch

6402e1
From 3234488f2c52a021eec87df1990d256314c21bff Mon Sep 17 00:00:00 2001
6402e1
From: Josef Moellers <jmoellers@suse.de>
6402e1
Date: Wed, 14 Apr 2021 16:39:28 +0200
6402e1
Subject: [PATCH] pam_limits: "Unlimited" is not a valid value for
6402e1
 RLIMIT_NOFILE.
6402e1
6402e1
Replace it with a value obtained from /proc/sys/fs/nr_open
6402e1
6402e1
* modules/pam_limits/limits.conf.5.xml: Document the replacement.
6402e1
* modules/pam_limits/pam_limits.c: Replace unlimited RLIMIT_NOFILE
6402e1
  value with a value obtained from /proc/sys/fs/nr_open
6402e1
---
6402e1
 modules/pam_limits/limits.conf.5.xml |  2 ++
6402e1
 modules/pam_limits/pam_limits.c      | 49 ++++++++++++++++++++++++++++
6402e1
 2 files changed, 51 insertions(+)
6402e1
6402e1
diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml
6402e1
index cd64ac90..c5bd6768 100644
6402e1
--- a/modules/pam_limits/limits.conf.5.xml
6402e1
+++ b/modules/pam_limits/limits.conf.5.xml
6402e1
@@ -283,6 +283,8 @@
6402e1
       <emphasis>unlimited</emphasis> or <emphasis>infinity</emphasis> indicating no limit,
6402e1
       except for <emphasis remap='B'>priority</emphasis>, <emphasis remap='B'>nice</emphasis>,
6402e1
       and <emphasis remap='B'>nonewprivs</emphasis>.
6402e1
+      If <emphasis remap='B'>nofile</emphasis> is to be set to one of these values,
6402e1
+      it will be set to the contents of /proc/sys/fs/nr_open instead (see setrlimit(3)).
6402e1
     </para>
6402e1
     <para>
6402e1
       If a hard limit or soft limit of a resource is set to a valid value,
6402e1
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
6402e1
index 10049973..7cc45d77 100644
6402e1
--- a/modules/pam_limits/pam_limits.c
6402e1
+++ b/modules/pam_limits/pam_limits.c
6402e1
@@ -487,6 +487,41 @@ static int init_limits(pam_handle_t *pamh, struct pam_limit_s *pl, int ctrl)
6402e1
     return retval;
6402e1
 }
6402e1
 
6402e1
+/*
6402e1
+ * Read the contents of <pathname> and return it in *valuep
6402e1
+ * return 1 if conversion succeeds, result is in *valuep
6402e1
+ * return 0 if conversion fails, *valuep is untouched.
6402e1
+ */
6402e1
+static int
6402e1
+value_from_file(const char *pathname, rlim_t *valuep)
6402e1
+{
6402e1
+    char buf[128];
6402e1
+    FILE *fp;
6402e1
+    int retval;
6402e1
+
6402e1
+    retval = 0;
6402e1
+
6402e1
+    if ((fp = fopen(pathname, "r")) != NULL) {
6402e1
+	if (fgets(buf, sizeof(buf), fp) != NULL) {
6402e1
+	    char *endptr;
6402e1
+	    unsigned long long value;
6402e1
+
6402e1
+	    errno = 0;
6402e1
+	    value = strtoull(buf, &endptr, 10);
6402e1
+	    if (endptr != buf &&
6402e1
+		(value != ULLONG_MAX || errno == 0) &&
6402e1
+                (unsigned long long) (rlim_t) value == value) {
6402e1
+		*valuep = (rlim_t) value;
6402e1
+		retval = 1;
6402e1
+	    }
6402e1
+	}
6402e1
+
6402e1
+	fclose(fp);
6402e1
+    }
6402e1
+
6402e1
+    return retval;
6402e1
+}
6402e1
+
6402e1
 static void
6402e1
 process_limit (const pam_handle_t *pamh, int source, const char *lim_type,
6402e1
 	       const char *lim_item, const char *lim_value,
6402e1
@@ -666,6 +701,20 @@ process_limit (const pam_handle_t *pamh, int source, const char *lim_type,
6402e1
 	 rlimit_value = 20 - int_value;
6402e1
          break;
6402e1
 #endif
6402e1
+	case RLIMIT_NOFILE:
6402e1
+	/*
6402e1
+	 * If nofile is to be set to "unlimited", try to set it to
6402e1
+	 * the value in /proc/sys/fs/nr_open instead.
6402e1
+	 */
6402e1
+	if (rlimit_value == RLIM_INFINITY) {
6402e1
+	    if (!value_from_file("/proc/sys/fs/nr_open", &rlimit_value))
6402e1
+		pam_syslog(pamh, LOG_WARNING,
6402e1
+			   "Cannot set \"nofile\" to a sensible value");
6402e1
+	    else if (ctrl & PAM_DEBUG_ARG)
6402e1
+		pam_syslog(pamh, LOG_DEBUG, "Setting \"nofile\" limit to %llu",
6402e1
+			   (unsigned long long) rlimit_value);
6402e1
+	}
6402e1
+	break;
6402e1
     }
6402e1
 
6402e1
     if ( (limit_item != LIMIT_LOGIN)
6402e1
-- 
6402e1
2.33.1
6402e1