Blob Blame Raw
diff -up sudo-1.8.6p3/src/exec.c.nprocfix sudo-1.8.6p3/src/exec.c
--- sudo-1.8.6p3/src/exec.c.nprocfix	2013-07-11 12:55:10.686308050 +0200
+++ sudo-1.8.6p3/src/exec.c	2013-07-11 12:54:21.159160553 +0200
@@ -132,6 +132,15 @@ static int fork_cmnd(struct command_deta
     if (policy_init_session(details) != true)
 	errorx(1, _("policy plugin failed session initialization"));
 
+    /*
+     * See the comment in unlimit_nproc. It is important to call
+     * this function AFTER policy_init_session, because the PAM
+     * subsystem, if used, may change the RLIMIT_NPROC limit to
+     * unlimited (infinity) and we would not be able to distinguish
+     * between our temporary change and the change done by PAM.
+     */
+    unlimit_nproc();
+
     cmnd_pid = sudo_debug_fork();
     switch (cmnd_pid) {
     case -1:
diff -up sudo-1.8.6p3/src/exec_pty.c.nprocfix sudo-1.8.6p3/src/exec_pty.c
--- sudo-1.8.6p3/src/exec_pty.c.nprocfix	2012-09-18 15:57:43.000000000 +0200
+++ sudo-1.8.6p3/src/exec_pty.c	2013-07-11 12:37:41.811202301 +0200
@@ -678,6 +678,15 @@ fork_pty(struct command_details *details
 	errorx(1, _("policy plugin failed session initialization"));
 
     /*
+     * See the comment in unlimit_nproc. It is important to call
+     * this function AFTER policy_init_session, because the PAM
+     * subsystem, if used, may change the RLIMIT_NPROC limit to
+     * unlimited (infinity) and we would not be able to distinguish
+     * between our temporary change and the change done by PAM.
+     */
+    unlimit_nproc();
+
+    /*
      * Block some signals until cmnd_pid is set in the parent to avoid a
      * race between exec of the command and receipt of a fatal signal from it.
      */
diff -up sudo-1.8.6p3/src/sudo.c.nprocfix sudo-1.8.6p3/src/sudo.c
--- sudo-1.8.6p3/src/sudo.c.nprocfix	2013-07-11 12:37:41.767202170 +0200
+++ sudo-1.8.6p3/src/sudo.c	2013-07-11 12:37:41.811202301 +0200
@@ -808,25 +808,11 @@ sudo_check_suid(const char *path)
 static void
 disable_coredumps(void)
 {
-#if defined(__linux__) || defined(RLIMIT_CORE)
-    struct rlimit rl;
+#if defined(RLIMIT_CORE)
+		struct rlimit rl;
 #endif
     debug_decl(disable_coredumps, SUDO_DEBUG_UTIL)
 
-#if defined(__linux__)
-    /*
-     * Unlimit the number of processes since Linux's setuid() will
-     * apply resource limits when changing uid and return EAGAIN if
-     * nproc would be violated by the uid switch.
-     */
-    (void) getrlimit(RLIMIT_NPROC, &nproclimit);
-    rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
-    if (setrlimit(RLIMIT_NPROC, &rl)) {
-	memcpy(&rl, &nproclimit, sizeof(struct rlimit));
-	rl.rlim_cur = rl.rlim_max;
-	(void)setrlimit(RLIMIT_NPROC, &rl);
-    }
-#endif /* __linux__ */
 #ifdef RLIMIT_CORE
     /*
      * Turn off core dumps?
@@ -841,6 +827,28 @@ disable_coredumps(void)
     debug_return;
 }
 
+void
+unlimit_nproc(void)
+{
+	debug_decl(unlimit_nproc, SUDO_DEBUG_UTIL)
+#if defined(__linux__)
+		struct rlimit rl;
+	/*
+    * Unlimit the number of processes since Linux's setuid() will
+    * apply resource limits when changing uid and return EAGAIN if
+    * nproc would be violated by the uid switch.
+    */
+	(void) getrlimit(RLIMIT_NPROC, &nproclimit);
+	rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
+	if (setrlimit(RLIMIT_NPROC, &rl)) {
+		memcpy(&rl, &nproclimit, sizeof(struct rlimit));
+		rl.rlim_cur = rl.rlim_max;
+		(void)setrlimit(RLIMIT_NPROC, &rl);
+	}
+#endif /* __linux__ */
+	debug_return;
+}
+
 #ifdef HAVE_PROJECT_H
 static void
 set_project(struct passwd *pw)
@@ -1082,7 +1090,6 @@ exec_setup(struct command_details *detai
 	errno = 0;
 	l = sysconf(_SC_CHILD_MAX);
 	if (l == -1 && errno == 0 && getrlimit(RLIMIT_NPROC, &rl) == 0) {
-	    if (rl.rlim_cur == RLIM_INFINITY && rl.rlim_max == RLIM_INFINITY)
 		(void) setrlimit(RLIMIT_NPROC, &nproclimit);
 	}
     }
diff -up sudo-1.8.6p3/src/sudo.h.nprocfix sudo-1.8.6p3/src/sudo.h
--- sudo-1.8.6p3/src/sudo.h.nprocfix	2013-07-11 12:37:41.768202173 +0200
+++ sudo-1.8.6p3/src/sudo.h	2013-07-11 12:37:41.811202301 +0200
@@ -219,6 +219,7 @@ int policy_init_session(struct command_d
 int run_command(struct command_details *details);
 extern const char *list_user, *runas_user, *runas_group;
 extern struct user_details user_details;
+void unlimit_nproc(void);
 
 /* sudo_edit.c */
 int sudo_edit(struct command_details *details);