Zdenek Dohnal 529fc9
From d47f6aec436e0e9df6554436e391471097686ecc Mon Sep 17 00:00:00 2001
Zdenek Dohnal 529fc9
From: Michael R Sweet <michael.r.sweet@gmail.com>
Zdenek Dohnal 529fc9
Date: Tue, 8 May 2018 15:24:21 -0700
Zdenek Dohnal 529fc9
Subject: [PATCH] Fix local privilege escalation to root and sandbox bypasses
Zdenek Dohnal 529fc9
 in scheduler (rdar://37836779, rdar://37836995, rdar://37837252,
Zdenek Dohnal 529fc9
 rdar://37837581)
Zdenek Dohnal 529fc9
Zdenek Dohnal 529fc9
---
Zdenek Dohnal 529fc9
 man/cups-files.conf.man.in |  10 ++
Zdenek Dohnal 529fc9
 man/cupsd.conf.man.in      |   8 --
Zdenek Dohnal 529fc9
 scheduler/conf.c           | 201 +++++++++++++++++++++++--------------
Zdenek Dohnal 529fc9
 scheduler/job.c            |  12 +++
Zdenek Dohnal 529fc9
 scheduler/process.c        |  16 +--
Zdenek Dohnal 529fc9
 scheduler/server.c         |  20 +++-
Zdenek Dohnal 529fc9
 test/run-stp-tests.sh      |  11 +-
Zdenek Dohnal 529fc9
 7 files changed, 179 insertions(+), 99 deletions(-)
Zdenek Dohnal 529fc9
Zdenek Dohnal 529fc9
diff --git a/man/cups-files.conf.man.in b/man/cups-files.conf.man.in
Zdenek Dohnal 529fc9
index 7b96d687d..baf3cb6af 100644
Zdenek Dohnal 529fc9
--- a/man/cups-files.conf.man.in
Zdenek Dohnal 529fc9
+++ b/man/cups-files.conf.man.in
Zdenek Dohnal 529fc9
@@ -153,6 +153,11 @@ The server name may be included in filenames using the string "%s", for example:
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
 .fi
Zdenek Dohnal 529fc9
 The default is "/var/log/cups/page_log".
Zdenek Dohnal 529fc9
+.\"#PassEnv
Zdenek Dohnal 529fc9
+.TP 5
Zdenek Dohnal 529fc9
+\fBPassEnv \fIvariable \fR[ ... \fIvariable \fR]
Zdenek Dohnal 529fc9
+Passes the specified environment variable(s) to child processes.
Zdenek Dohnal 529fc9
+Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive.
Zdenek Dohnal 529fc9
 .\"#RemoteRoot
Zdenek Dohnal 529fc9
 .TP 5
Zdenek Dohnal 529fc9
 \fBRemoteRoot \fIusername\fR
Zdenek Dohnal 529fc9
@@ -187,6 +192,11 @@ macOS uses its keychain database to store certificates and keys while other plat
Zdenek Dohnal 529fc9
 \fBServerRoot \fIdirectory\fR
Zdenek Dohnal 529fc9
 Specifies the directory containing the server configuration files.
Zdenek Dohnal 529fc9
 The default is "/etc/cups".
Zdenek Dohnal 529fc9
+.\"#SetEnv
Zdenek Dohnal 529fc9
+.TP 5
Zdenek Dohnal 529fc9
+\fBSetEnv \fIvariable value\fR
Zdenek Dohnal 529fc9
+Set the specified environment variable to be passed to child processes.
Zdenek Dohnal 529fc9
+Note: the standard CUPS filter and backend environment variables cannot be overridden using this directive.
Zdenek Dohnal 529fc9
 .\"#StateDir
Zdenek Dohnal 529fc9
 .TP 5
Zdenek Dohnal 529fc9
 \fBStateDir \fIdirectory\fR
Zdenek Dohnal 529fc9
diff --git a/man/cupsd.conf.man.in b/man/cupsd.conf.man.in
Zdenek Dohnal 529fc9
index 3ffc80e42..36c849398 100644
Zdenek Dohnal 529fc9
--- a/man/cupsd.conf.man.in
Zdenek Dohnal 529fc9
+++ b/man/cupsd.conf.man.in
Zdenek Dohnal 529fc9
@@ -349,10 +349,6 @@ The default is "1048576" (1MB).
Zdenek Dohnal 529fc9
 \fBMultipleOperationTimeout \fIseconds\fR
Zdenek Dohnal 529fc9
 Specifies the maximum amount of time to allow between files in a multiple file print job.
Zdenek Dohnal 529fc9
 The default is "300" (5 minutes).
Zdenek Dohnal 529fc9
-.\"#PassEnv
Zdenek Dohnal 529fc9
-.TP 5
Zdenek Dohnal 529fc9
-\fBPassEnv \fIvariable \fR[ ... \fIvariable \fR]
Zdenek Dohnal 529fc9
-Passes the specified environment variable(s) to child processes.
Zdenek Dohnal 529fc9
 .\"#Policy
Zdenek Dohnal 529fc9
 .TP 5
Zdenek Dohnal 529fc9
 \fB<Policy \fIname\fB> \fR... \fB</Policy>\fR
Zdenek Dohnal 529fc9
@@ -433,10 +429,6 @@ Specifies what information is included in the Server header of HTTP responses.
Zdenek Dohnal 529fc9
 command.
Zdenek Dohnal 529fc9
 "Full" reports "CUPS 2.0.0 (UNAME) IPP/2.0".
Zdenek Dohnal 529fc9
 The default is "Minimal".
Zdenek Dohnal 529fc9
-.\"#SetEnv
Zdenek Dohnal 529fc9
-.TP 5
Zdenek Dohnal 529fc9
-\fBSetEnv \fIvariable value\fR
Zdenek Dohnal 529fc9
-Set the specified environment variable to be passed to child processes.
Zdenek Dohnal 529fc9
 .\"#SSLListen
Zdenek Dohnal 529fc9
 .TP 5
Zdenek Dohnal 529fc9
 \fBSSLListen \fIipv4-address\fB:\fIport\fR
Zdenek Dohnal 529fc9
diff --git a/scheduler/conf.c b/scheduler/conf.c
Zdenek Dohnal 529fc9
index 67a91e7a6..b51c6060c 100644
Zdenek Dohnal 529fc9
--- a/scheduler/conf.c
Zdenek Dohnal 529fc9
+++ b/scheduler/conf.c
Zdenek Dohnal 529fc9
@@ -2929,13 +2929,10 @@ read_cupsd_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
 					/* Line from file */
Zdenek Dohnal 529fc9
 			temp[HTTP_MAX_BUFFER],
Zdenek Dohnal 529fc9
 					/* Temporary buffer for value */
Zdenek Dohnal 529fc9
-			*value,		/* Pointer to value */
Zdenek Dohnal 529fc9
-			*valueptr;	/* Pointer into value */
Zdenek Dohnal 529fc9
+			*value;		/* Pointer to value */
Zdenek Dohnal 529fc9
   int			valuelen;	/* Length of value */
Zdenek Dohnal 529fc9
   http_addrlist_t	*addrlist,	/* Address list */
Zdenek Dohnal 529fc9
 			*addr;		/* Current address */
Zdenek Dohnal 529fc9
-  cups_file_t		*incfile;	/* Include file */
Zdenek Dohnal 529fc9
-  char			incname[1024];	/* Include filename */
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
  /*
Zdenek Dohnal 529fc9
@@ -2950,28 +2947,7 @@ read_cupsd_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
     * Decode the directive...
Zdenek Dohnal 529fc9
     */
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
-    if (!_cups_strcasecmp(line, "Include") && value)
Zdenek Dohnal 529fc9
-    {
Zdenek Dohnal 529fc9
-     /*
Zdenek Dohnal 529fc9
-      * Include filename
Zdenek Dohnal 529fc9
-      */
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-      if (value[0] == '/')
Zdenek Dohnal 529fc9
-        strlcpy(incname, value, sizeof(incname));
Zdenek Dohnal 529fc9
-      else
Zdenek Dohnal 529fc9
-        snprintf(incname, sizeof(incname), "%s/%s", ServerRoot, value);
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-      if ((incfile = cupsFileOpen(incname, "rb")) == NULL)
Zdenek Dohnal 529fc9
-        cupsdLogMessage(CUPSD_LOG_ERROR,
Zdenek Dohnal 529fc9
-	                "Unable to include config file \"%s\" - %s",
Zdenek Dohnal 529fc9
-	                incname, strerror(errno));
Zdenek Dohnal 529fc9
-      else
Zdenek Dohnal 529fc9
-      {
Zdenek Dohnal 529fc9
-        read_cupsd_conf(incfile);
Zdenek Dohnal 529fc9
-	cupsFileClose(incfile);
Zdenek Dohnal 529fc9
-      }
Zdenek Dohnal 529fc9
-    }
Zdenek Dohnal 529fc9
-    else if (!_cups_strcasecmp(line, "
Zdenek Dohnal 529fc9
+    if (!_cups_strcasecmp(line, "
Zdenek Dohnal 529fc9
     {
Zdenek Dohnal 529fc9
      /*
Zdenek Dohnal 529fc9
       * <Location path>
Zdenek Dohnal 529fc9
@@ -3367,31 +3343,6 @@ read_cupsd_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
 	cupsdLogMessage(CUPSD_LOG_WARN, "Unknown ServerTokens %s on line %d of %s.",
Zdenek Dohnal 529fc9
                         value, linenum, ConfigurationFile);
Zdenek Dohnal 529fc9
     }
Zdenek Dohnal 529fc9
-    else if (!_cups_strcasecmp(line, "PassEnv") && value)
Zdenek Dohnal 529fc9
-    {
Zdenek Dohnal 529fc9
-     /*
Zdenek Dohnal 529fc9
-      * PassEnv variable [... variable]
Zdenek Dohnal 529fc9
-      */
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-      for (; *value;)
Zdenek Dohnal 529fc9
-      {
Zdenek Dohnal 529fc9
-        for (valuelen = 0; value[valuelen]; valuelen ++)
Zdenek Dohnal 529fc9
-	  if (_cups_isspace(value[valuelen]) || value[valuelen] == ',')
Zdenek Dohnal 529fc9
-	    break;
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-        if (value[valuelen])
Zdenek Dohnal 529fc9
-        {
Zdenek Dohnal 529fc9
-	  value[valuelen] = '\0';
Zdenek Dohnal 529fc9
-	  valuelen ++;
Zdenek Dohnal 529fc9
-	}
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-        cupsdSetEnv(value, NULL);
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-        for (value += valuelen; *value; value ++)
Zdenek Dohnal 529fc9
-	  if (!_cups_isspace(*value) || *value != ',')
Zdenek Dohnal 529fc9
-	    break;
Zdenek Dohnal 529fc9
-      }
Zdenek Dohnal 529fc9
-    }
Zdenek Dohnal 529fc9
     else if (!_cups_strcasecmp(line, "ServerAlias") && value)
Zdenek Dohnal 529fc9
     {
Zdenek Dohnal 529fc9
      /*
Zdenek Dohnal 529fc9
@@ -3420,30 +3371,6 @@ read_cupsd_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
 	    break;
Zdenek Dohnal 529fc9
       }
Zdenek Dohnal 529fc9
     }
Zdenek Dohnal 529fc9
-    else if (!_cups_strcasecmp(line, "SetEnv") && value)
Zdenek Dohnal 529fc9
-    {
Zdenek Dohnal 529fc9
-     /*
Zdenek Dohnal 529fc9
-      * SetEnv variable value
Zdenek Dohnal 529fc9
-      */
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-      if (*valueptr)
Zdenek Dohnal 529fc9
-      {
Zdenek Dohnal 529fc9
-       /*
Zdenek Dohnal 529fc9
-        * Found a value...
Zdenek Dohnal 529fc9
-	*/
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-        while (isspace(*valueptr & 255))
Zdenek Dohnal 529fc9
-	  *valueptr++ = '\0';
Zdenek Dohnal 529fc9
-
Zdenek Dohnal 529fc9
-        cupsdSetEnv(value, valueptr);
Zdenek Dohnal 529fc9
-      }
Zdenek Dohnal 529fc9
-      else
Zdenek Dohnal 529fc9
-        cupsdLogMessage(CUPSD_LOG_ERROR,
Zdenek Dohnal 529fc9
-	                "Missing value for SetEnv directive on line %d of %s.",
Zdenek Dohnal 529fc9
-	                linenum, ConfigurationFile);
Zdenek Dohnal 529fc9
-    }
Zdenek Dohnal 529fc9
     else if (!_cups_strcasecmp(line, "AccessLog") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "CacheDir") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "ConfigFilePerm") ||
Zdenek Dohnal 529fc9
@@ -3457,6 +3384,7 @@ read_cupsd_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "LogFilePerm") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "LPDConfigFile") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "PageLog") ||
Zdenek Dohnal 529fc9
+             !_cups_strcasecmp(line, "PassEnv") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "Printcap") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "PrintcapFormat") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "RemoteRoot") ||
Zdenek Dohnal 529fc9
@@ -3466,6 +3394,7 @@ read_cupsd_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "ServerKey") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "ServerKeychain") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "ServerRoot") ||
Zdenek Dohnal 529fc9
+             !_cups_strcasecmp(line, "SetEnv") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "SMBConfigFile") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "StateDir") ||
Zdenek Dohnal 529fc9
              !_cups_strcasecmp(line, "SystemGroup") ||
Zdenek Dohnal 529fc9
@@ -3495,10 +3424,49 @@ read_cupsd_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
 static int				/* O - 1 on success, 0 on failure */
Zdenek Dohnal 529fc9
 read_cups_files_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
 {
Zdenek Dohnal 529fc9
-  int		linenum;		/* Current line number */
Zdenek Dohnal 529fc9
+  int		i,			/* Looping var */
Zdenek Dohnal 529fc9
+		linenum;		/* Current line number */
Zdenek Dohnal 529fc9
   char		line[HTTP_MAX_BUFFER],	/* Line from file */
Zdenek Dohnal 529fc9
 		*value;			/* Value from line */
Zdenek Dohnal 529fc9
   struct group	*group;			/* Group */
Zdenek Dohnal 529fc9
+  static const char * const prohibited_env[] =
Zdenek Dohnal 529fc9
+  {					/* Prohibited environment variables */
Zdenek Dohnal 529fc9
+    "APPLE_LANGUAGE",
Zdenek Dohnal 529fc9
+    "AUTH_DOMAIN",
Zdenek Dohnal 529fc9
+    "AUTH_INFO_REQUIRED",
Zdenek Dohnal 529fc9
+    "AUTH_NEGOTIATE",
Zdenek Dohnal 529fc9
+    "AUTH_PASSWORD",
Zdenek Dohnal 529fc9
+    "AUTH_UID",
Zdenek Dohnal 529fc9
+    "AUTH_USERNAME",
Zdenek Dohnal 529fc9
+    "CHARSET",
Zdenek Dohnal 529fc9
+    "CLASS",
Zdenek Dohnal 529fc9
+    "CLASSIFICATION",
Zdenek Dohnal 529fc9
+    "CONTENT_TYPE",
Zdenek Dohnal 529fc9
+    "CUPS_CACHEDIR",
Zdenek Dohnal 529fc9
+    "CUPS_DATADIR",
Zdenek Dohnal 529fc9
+    "CUPS_DOCROOT",
Zdenek Dohnal 529fc9
+    "CUPS_FILETYPE",
Zdenek Dohnal 529fc9
+    "CUPS_FONTPATH",
Zdenek Dohnal 529fc9
+    "CUPS_MAX_MESSAGE",
Zdenek Dohnal 529fc9
+    "CUPS_REQUESTROOT",
Zdenek Dohnal 529fc9
+    "CUPS_SERVERBIN",
Zdenek Dohnal 529fc9
+    "CUPS_SERVERROOT",
Zdenek Dohnal 529fc9
+    "CUPS_STATEDIR",
Zdenek Dohnal 529fc9
+    "DEVICE_URI",
Zdenek Dohnal 529fc9
+    "FINAL_CONTENT_TYPE",
Zdenek Dohnal 529fc9
+    "HOME",
Zdenek Dohnal 529fc9
+    "LANG",
Zdenek Dohnal 529fc9
+    "PPD",
Zdenek Dohnal 529fc9
+    "PRINTER",
Zdenek Dohnal 529fc9
+    "PRINTER_INFO",
Zdenek Dohnal 529fc9
+    "PRINTER_LOCATION",
Zdenek Dohnal 529fc9
+    "PRINTER_STATE_REASONS",
Zdenek Dohnal 529fc9
+    "RIP_CACHE",
Zdenek Dohnal 529fc9
+    "SERVER_ADMIN",
Zdenek Dohnal 529fc9
+    "SOFTWARE",
Zdenek Dohnal 529fc9
+    "TMPDIR",
Zdenek Dohnal 529fc9
+    "USER"
Zdenek Dohnal 529fc9
+  };
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
  /*
Zdenek Dohnal 529fc9
@@ -3536,6 +3504,47 @@ read_cups_files_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
 	}
Zdenek Dohnal 529fc9
       }
Zdenek Dohnal 529fc9
     }
Zdenek Dohnal 529fc9
+    else if (!_cups_strcasecmp(line, "PassEnv") && value)
Zdenek Dohnal 529fc9
+    {
Zdenek Dohnal 529fc9
+     /*
Zdenek Dohnal 529fc9
+      * PassEnv variable [... variable]
Zdenek Dohnal 529fc9
+      */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+      int valuelen;			/* Length of variable name */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+      for (; *value;)
Zdenek Dohnal 529fc9
+      {
Zdenek Dohnal 529fc9
+        for (valuelen = 0; value[valuelen]; valuelen ++)
Zdenek Dohnal 529fc9
+	  if (_cups_isspace(value[valuelen]) || value[valuelen] == ',')
Zdenek Dohnal 529fc9
+	    break;
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+        if (value[valuelen])
Zdenek Dohnal 529fc9
+        {
Zdenek Dohnal 529fc9
+	  value[valuelen] = '\0';
Zdenek Dohnal 529fc9
+	  valuelen ++;
Zdenek Dohnal 529fc9
+	}
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+        for (i = 0; i < (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])); i ++)
Zdenek Dohnal 529fc9
+        {
Zdenek Dohnal 529fc9
+          if (!strcmp(value, prohibited_env[i]))
Zdenek Dohnal 529fc9
+          {
Zdenek Dohnal 529fc9
+	    cupsdLogMessage(CUPSD_LOG_ERROR, "Environment variable \"%s\" cannot be passed through on line %d of %s.", value, linenum, CupsFilesFile);
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+	    if (FatalErrors & CUPSD_FATAL_CONFIG)
Zdenek Dohnal 529fc9
+	      return (0);
Zdenek Dohnal 529fc9
+	    else
Zdenek Dohnal 529fc9
+	      break;
Zdenek Dohnal 529fc9
+          }
Zdenek Dohnal 529fc9
+	}
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+        if (i >= (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])))
Zdenek Dohnal 529fc9
+          cupsdSetEnv(value, NULL);
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+        for (value += valuelen; *value; value ++)
Zdenek Dohnal 529fc9
+	  if (!_cups_isspace(*value) || *value != ',')
Zdenek Dohnal 529fc9
+	    break;
Zdenek Dohnal 529fc9
+      }
Zdenek Dohnal 529fc9
+    }
Zdenek Dohnal 529fc9
     else if (!_cups_strcasecmp(line, "PrintcapFormat") && value)
Zdenek Dohnal 529fc9
     {
Zdenek Dohnal 529fc9
      /*
Zdenek Dohnal 529fc9
@@ -3581,6 +3590,46 @@ read_cups_files_conf(cups_file_t *fp)	/* I - File to read from */
Zdenek Dohnal 529fc9
           return (0);
Zdenek Dohnal 529fc9
       }
Zdenek Dohnal 529fc9
     }
Zdenek Dohnal 529fc9
+    else if (!_cups_strcasecmp(line, "SetEnv") && value)
Zdenek Dohnal 529fc9
+    {
Zdenek Dohnal 529fc9
+     /*
Zdenek Dohnal 529fc9
+      * SetEnv variable value
Zdenek Dohnal 529fc9
+      */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+      char *valueptr;			/* Pointer to environment variable value */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+      for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+      if (*valueptr)
Zdenek Dohnal 529fc9
+      {
Zdenek Dohnal 529fc9
+       /*
Zdenek Dohnal 529fc9
+        * Found a value...
Zdenek Dohnal 529fc9
+	*/
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+        while (isspace(*valueptr & 255))
Zdenek Dohnal 529fc9
+	  *valueptr++ = '\0';
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+        for (i = 0; i < (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])); i ++)
Zdenek Dohnal 529fc9
+        {
Zdenek Dohnal 529fc9
+          if (!strcmp(value, prohibited_env[i]))
Zdenek Dohnal 529fc9
+          {
Zdenek Dohnal 529fc9
+	    cupsdLogMessage(CUPSD_LOG_ERROR, "Environment variable \"%s\" cannot be set  on line %d of %s.", value, linenum, CupsFilesFile);
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+	    if (FatalErrors & CUPSD_FATAL_CONFIG)
Zdenek Dohnal 529fc9
+	      return (0);
Zdenek Dohnal 529fc9
+	    else
Zdenek Dohnal 529fc9
+	      break;
Zdenek Dohnal 529fc9
+          }
Zdenek Dohnal 529fc9
+	}
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+        if (i >= (int)(sizeof(prohibited_env) / sizeof(prohibited_env[0])))
Zdenek Dohnal 529fc9
+	  cupsdSetEnv(value, valueptr);
Zdenek Dohnal 529fc9
+      }
Zdenek Dohnal 529fc9
+      else
Zdenek Dohnal 529fc9
+        cupsdLogMessage(CUPSD_LOG_ERROR,
Zdenek Dohnal 529fc9
+	                "Missing value for SetEnv directive on line %d of %s.",
Zdenek Dohnal 529fc9
+	                linenum, ConfigurationFile);
Zdenek Dohnal 529fc9
+    }
Zdenek Dohnal 529fc9
     else if (!_cups_strcasecmp(line, "SystemGroup") && value)
Zdenek Dohnal 529fc9
     {
Zdenek Dohnal 529fc9
      /*
Zdenek Dohnal 529fc9
diff --git a/scheduler/job.c b/scheduler/job.c
Zdenek Dohnal 529fc9
index 61cda44e2..5ced0b9d1 100644
Zdenek Dohnal 529fc9
--- a/scheduler/job.c
Zdenek Dohnal 529fc9
+++ b/scheduler/job.c
Zdenek Dohnal 529fc9
@@ -4779,6 +4779,18 @@ start_job(cupsd_job_t     *job,		/* I - Job ID */
Zdenek Dohnal 529fc9
   job->profile  = cupsdCreateProfile(job->id, 0);
Zdenek Dohnal 529fc9
   job->bprofile = cupsdCreateProfile(job->id, 1);
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
+#ifdef HAVE_SANDBOX_H
Zdenek Dohnal 529fc9
+  if ((!job->profile || !job->bprofile) && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF)
Zdenek Dohnal 529fc9
+  {
Zdenek Dohnal 529fc9
+   /*
Zdenek Dohnal 529fc9
+    * Failure to create the sandbox profile means something really bad has
Zdenek Dohnal 529fc9
+    * happened and we need to shutdown immediately.
Zdenek Dohnal 529fc9
+    */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+    return;
Zdenek Dohnal 529fc9
+  }
Zdenek Dohnal 529fc9
+#endif /* HAVE_SANDBOX_H */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
  /*
Zdenek Dohnal 529fc9
   * Create the status pipes and buffer...
Zdenek Dohnal 529fc9
   */
Zdenek Dohnal 529fc9
diff --git a/scheduler/process.c b/scheduler/process.c
Zdenek Dohnal 529fc9
index b8d49d8f0..3c1c6ba4f 100644
Zdenek Dohnal 529fc9
--- a/scheduler/process.c
Zdenek Dohnal 529fc9
+++ b/scheduler/process.c
Zdenek Dohnal 529fc9
@@ -98,9 +98,13 @@ cupsdCreateProfile(int job_id,		/* I - Job ID or 0 for none */
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
   if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL)
Zdenek Dohnal 529fc9
   {
Zdenek Dohnal 529fc9
+   /*
Zdenek Dohnal 529fc9
+    * This should never happen, and is fatal when sandboxing is enabled.
Zdenek Dohnal 529fc9
+    */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
     cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d, allow_networking=%d) = NULL", job_id, allow_networking);
Zdenek Dohnal 529fc9
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create security profile: %s",
Zdenek Dohnal 529fc9
-                    strerror(errno));
Zdenek Dohnal 529fc9
+    cupsdLogMessage(CUPSD_LOG_EMERG, "Unable to create security profile: %s", strerror(errno));
Zdenek Dohnal 529fc9
+    kill(getpid(), SIGTERM);
Zdenek Dohnal 529fc9
     return (NULL);
Zdenek Dohnal 529fc9
   }
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
@@ -197,10 +201,8 @@ cupsdCreateProfile(int job_id,		/* I - Job ID or 0 for none */
Zdenek Dohnal 529fc9
 		 " #\"^%s/\""		/* TempDir/... */
Zdenek Dohnal 529fc9
 		 " #\"^%s$\""		/* CacheDir */
Zdenek Dohnal 529fc9
 		 " #\"^%s/\""		/* CacheDir/... */
Zdenek Dohnal 529fc9
-		 " #\"^%s$\""		/* StateDir */
Zdenek Dohnal 529fc9
-		 " #\"^%s/\""		/* StateDir/... */
Zdenek Dohnal 529fc9
 		 "))\n",
Zdenek Dohnal 529fc9
-		 temp, temp, cache, cache, state, state);
Zdenek Dohnal 529fc9
+		 temp, temp, cache, cache);
Zdenek Dohnal 529fc9
   /* Read common folders */
Zdenek Dohnal 529fc9
   cupsFilePrintf(fp,
Zdenek Dohnal 529fc9
                  "(allow file-read-data file-read-metadata\n"
Zdenek Dohnal 529fc9
@@ -242,8 +244,10 @@ cupsdCreateProfile(int job_id,		/* I - Job ID or 0 for none */
Zdenek Dohnal 529fc9
 		 " #\"^%s/\""		/* ServerBin/... */
Zdenek Dohnal 529fc9
 		 " #\"^%s$\""		/* ServerRoot */
Zdenek Dohnal 529fc9
 		 " #\"^%s/\""		/* ServerRoot/... */
Zdenek Dohnal 529fc9
+		 " #\"^%s$\""		/* StateDir */
Zdenek Dohnal 529fc9
+		 " #\"^%s/\""		/* StateDir/... */
Zdenek Dohnal 529fc9
 		 "))\n",
Zdenek Dohnal 529fc9
-		 request, request, bin, bin, root, root);
Zdenek Dohnal 529fc9
+		 request, request, bin, bin, root, root, state, state);
Zdenek Dohnal 529fc9
   if (Sandboxing == CUPSD_SANDBOXING_RELAXED)
Zdenek Dohnal 529fc9
   {
Zdenek Dohnal 529fc9
     /* Limited write access to /Library/Printers/... */
Zdenek Dohnal 529fc9
diff --git a/scheduler/server.c b/scheduler/server.c
Zdenek Dohnal 529fc9
index cecbabe67..a4033791b 100644
Zdenek Dohnal 529fc9
--- a/scheduler/server.c
Zdenek Dohnal 529fc9
+++ b/scheduler/server.c
Zdenek Dohnal 529fc9
@@ -34,16 +34,28 @@ void
Zdenek Dohnal 529fc9
 cupsdStartServer(void)
Zdenek Dohnal 529fc9
 {
Zdenek Dohnal 529fc9
  /*
Zdenek Dohnal 529fc9
-  * Start color management (as needed)...
Zdenek Dohnal 529fc9
+  * Create the default security profile...
Zdenek Dohnal 529fc9
   */
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
-  cupsdStartColor();
Zdenek Dohnal 529fc9
+  DefaultProfile = cupsdCreateProfile(0, 1);
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+#ifdef HAVE_SANDBOX_H
Zdenek Dohnal 529fc9
+  if (!DefaultProfile && UseSandboxing && Sandboxing != CUPSD_SANDBOXING_OFF)
Zdenek Dohnal 529fc9
+  {
Zdenek Dohnal 529fc9
+   /*
Zdenek Dohnal 529fc9
+    * Failure to create the sandbox profile means something really bad has
Zdenek Dohnal 529fc9
+    * happened and we need to shutdown immediately.
Zdenek Dohnal 529fc9
+    */
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+    return;
Zdenek Dohnal 529fc9
+  }
Zdenek Dohnal 529fc9
+#endif /* HAVE_SANDBOX_H */
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
  /*
Zdenek Dohnal 529fc9
-  * Create the default security profile...
Zdenek Dohnal 529fc9
+  * Start color management (as needed)...
Zdenek Dohnal 529fc9
   */
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
-  DefaultProfile = cupsdCreateProfile(0, 1);
Zdenek Dohnal 529fc9
+  cupsdStartColor();
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
  /*
Zdenek Dohnal 529fc9
   * Startup all the networking stuff...
Zdenek Dohnal 529fc9
diff --git a/test/run-stp-tests.sh b/test/run-stp-tests.sh
Zdenek Dohnal 529fc9
index 7eb269a67..f83bd5d91 100755
Zdenek Dohnal 529fc9
--- a/test/run-stp-tests.sh
Zdenek Dohnal 529fc9
+++ b/test/run-stp-tests.sh
Zdenek Dohnal 529fc9
@@ -489,11 +489,6 @@ StrictConformance Yes
Zdenek Dohnal 529fc9
 Browsing Off
Zdenek Dohnal 529fc9
 Listen localhost:$port
Zdenek Dohnal 529fc9
 Listen $BASE/sock
Zdenek Dohnal 529fc9
-PassEnv DYLD_LIBRARY_PATH
Zdenek Dohnal 529fc9
-PassEnv LD_LIBRARY_PATH
Zdenek Dohnal 529fc9
-PassEnv LD_PRELOAD
Zdenek Dohnal 529fc9
-PassEnv LOCALEDIR
Zdenek Dohnal 529fc9
-PassEnv SHLIB_PATH
Zdenek Dohnal 529fc9
 MaxSubscriptions 3
Zdenek Dohnal 529fc9
 MaxLogSize 0
Zdenek Dohnal 529fc9
 AccessLogLevel actions
Zdenek Dohnal 529fc9
@@ -529,6 +524,12 @@ TempDir $BASE/spool/temp
Zdenek Dohnal 529fc9
 AccessLog $BASE/log/access_log
Zdenek Dohnal 529fc9
 ErrorLog $BASE/log/error_log
Zdenek Dohnal 529fc9
 PageLog $BASE/log/page_log
Zdenek Dohnal 529fc9
+
Zdenek Dohnal 529fc9
+PassEnv DYLD_LIBRARY_PATH
Zdenek Dohnal 529fc9
+PassEnv LD_LIBRARY_PATH
Zdenek Dohnal 529fc9
+PassEnv LD_PRELOAD
Zdenek Dohnal 529fc9
+PassEnv LOCALEDIR
Zdenek Dohnal 529fc9
+PassEnv SHLIB_PATH
Zdenek Dohnal 529fc9
 EOF
Zdenek Dohnal 529fc9
 
Zdenek Dohnal 529fc9
 if test $ssltype != 0 -a `uname` = Darwin; then
Zdenek Dohnal 529fc9
-- 
Zdenek Dohnal 529fc9
2.17.1
Zdenek Dohnal 529fc9