Backport of:

From 545354a80b9cc20d8b6916ca30542eab36c3b8bd Mon Sep 17 00:00:00 2001
From: Graham Dumpleton <Graham.Dumpleton@gmail.com>
Date: Wed, 18 Jun 2014 21:17:34 +1000
Subject: [PATCH] When there is any sort of error in setting up daemon process
 group, kill the process rather than risk running in an unexpected state.

---
 src/server/mod_wsgi.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 51 insertions(+), 3 deletions(-)

Index: mod-wsgi-3.4/mod_wsgi.c
===================================================================
--- mod-wsgi-3.4.orig/mod_wsgi.c	2014-11-18 10:58:26.668234317 -0500
+++ mod-wsgi-3.4/mod_wsgi.c	2014-11-18 11:05:27.806580674 -0500
@@ -10369,7 +10369,7 @@
 #endif
 }
 
-static void wsgi_setup_access(WSGIDaemonProcess *daemon)
+static int wsgi_setup_access(WSGIDaemonProcess *daemon)
 {
     /* Setup the umask for the effective user. */
 
@@ -10383,6 +10383,8 @@
             ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server,
                          "mod_wsgi (pid=%d): Unable to change root "
                          "directory to '%s'.", getpid(), daemon->group->root);
+
+            return -1;
         }
     }
 
@@ -10393,6 +10395,8 @@
             ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server,
                          "mod_wsgi (pid=%d): Unable to change working "
                          "directory to '%s'.", getpid(), daemon->group->home);
+
+            return -1;
         }
     }
     else if (geteuid()) {
@@ -10405,12 +10409,16 @@
                 ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server,
                              "mod_wsgi (pid=%d): Unable to change working "
                              "directory to '%s'.", getpid(), pwent->pw_dir);
+
+                return -1;
             }
         }
         else {
             ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server,
                          "mod_wsgi (pid=%d): Unable to determine home "
                          "directory for uid=%ld.", getpid(), (long)geteuid());
+
+            return -1;
         }
     }
     else {
@@ -10423,6 +10431,8 @@
                 ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server,
                              "mod_wsgi (pid=%d): Unable to change working "
                              "directory to '%s'.", getpid(), pwent->pw_dir);
+
+                return -1;
             }
         }
         else {
@@ -10430,13 +10440,15 @@
                          "mod_wsgi (pid=%d): Unable to determine home "
                          "directory for uid=%ld.", getpid(),
                          (long)daemon->group->uid);
+
+            return -1;
         }
     }
 
     /* Don't bother switch user/group if not root. */
 
     if (geteuid())
-        return;
+        return 0;
 
     /* Setup the daemon process real and effective group. */
 
@@ -10444,6 +10456,8 @@
         ap_log_error(APLOG_MARK, WSGI_LOG_ALERT(errno), wsgi_server,
                      "mod_wsgi (pid=%d): Unable to set group id to gid=%u.",
                      getpid(), (unsigned)daemon->group->gid);
+
+        return -1;
     }
     else {
         if (daemon->group->groups) {
@@ -10454,6 +10468,8 @@
                              "to set supplementary groups for uname=%s "
                              "of '%s'.", getpid(), daemon->group->user,
                              daemon->group->groups_list);
+
+                return -1;
             }
         }
         else if (initgroups(daemon->group->user, daemon->group->gid) == -1) {
@@ -10461,6 +10477,8 @@
                          wsgi_server, "mod_wsgi (pid=%d): Unable "
                          "to set groups for uname=%s and gid=%u.", getpid(),
                          daemon->group->user, (unsigned)daemon->group->gid);
+
+            return -1;
         }
     }
 
@@ -10478,12 +10496,25 @@
          * reached their process limit. In that case will be left
          * running as wrong user. Just exit on all failures to be
          * safe. Don't die immediately to avoid a fork bomb.
+         *
+         * We could just return -1 here and let the caller do the
+         * sleep() and exit() but this failure is critical enough
+         * that we still do it here so it is obvious that the issue
+         * is being addressed.
          */
 
+        ap_log_error(APLOG_MARK, APLOG_ALERT, 0, wsgi_server,
+                     "mod_wsgi (pid=%d): Failure to configure the "
+                     "daemon process correctly and process left in "
+                     "unspecified state. Restarting daemon process "
+                     "after delay.", getpid());
+
         sleep(20);
 
         exit(-1);
     }
+
+    return 0;
 }
 
 static int wsgi_setup_socket(WSGIProcessGroup *process)
@@ -11496,7 +11527,24 @@
 
         /* Setup daemon process user/group/umask etc. */
 
-        wsgi_setup_access(daemon);
+        if (wsgi_setup_access(daemon) == -1) {
+            /*
+             * If we get any failure from setting up the appropriate
+             * permissions or working directory for the daemon process
+             * then we exit the process. Don't die immediately to avoid
+             * a fork bomb.
+             */
+
+            ap_log_error(APLOG_MARK, APLOG_ALERT, 0, wsgi_server,
+                         "mod_wsgi (pid=%d): Failure to configure the "
+                         "daemon process correctly and process left in "
+                         "unspecified state. Restarting daemon process "
+                         "after delay.", getpid());
+
+            sleep(20);
+
+            exit(-1);
+        }
 
         /* Reinitialise accept mutex in daemon process. */
 
