Fix CVE-2016-1531
[exim.git] / src / src / exim.c
index 81bc51ec77354f4d612aa64635a67306e4ada3c5..beb5abc25aa373605a9b187cbdda25bb00472ac6 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2014 */
+/* Copyright (c) University of Cambridge 1995 - 2015 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 
@@ -3723,8 +3723,19 @@ if (running_in_test_harness) smtputf8_advertise_hosts = NULL;
 is a failure. It leaves the configuration file open so that the subsequent
 configuration data for delivery can be read if needed. */
 
+/* To be safe: change the working directory to /. */
+if (Uchdir("/") < 0)
+  {
+    perror("exim: chdir `/': ");
+    exit(EXIT_FAILURE);
+  }
+
 readconf_main();
 
+if (cleanup_environment() == FALSE)
+  log_write(0, LOG_PANIC_DIE, "Can't cleanup environment");
+
+
 /* If an action on specific messages is requested, or if a daemon or queue
 runner is being started, we need to know if Exim was called by an admin user.
 This is the case if the real user is root or exim, or if the real group is
@@ -3881,7 +3892,7 @@ TMPDIR macro, if this macro is defined. */
 #ifdef TMPDIR
   {
   uschar **p;
-  for (p = USS environ; *p != NULL; p++)
+  if (environ) for (p = USS environ; *p != NULL; p++)
     {
     if (Ustrncmp(*p, "TMPDIR=", 7) == 0 &&
         Ustrcmp(*p+7, TMPDIR) != 0)
@@ -3921,10 +3932,10 @@ else
     uschar **new;
     uschar **newp;
     int count = 0;
-    while (*p++ != NULL) count++;
+    if (environ) while (*p++ != NULL) count++;
     if (envtz == NULL) count++;
     newp = new = malloc(sizeof(uschar *) * (count + 1));
-    for (p = USS environ; *p != NULL; p++)
+    if (environ) for (p = USS environ; *p != NULL; p++)
       {
       if (Ustrncmp(*p, "TZ=", 3) == 0) continue;
       *newp++ = *p;
@@ -4514,7 +4525,8 @@ if (list_options)
           (Ustrcmp(argv[i], "router") == 0 ||
            Ustrcmp(argv[i], "transport") == 0 ||
            Ustrcmp(argv[i], "authenticator") == 0 ||
-           Ustrcmp(argv[i], "macro") == 0))
+           Ustrcmp(argv[i], "macro") == 0 ||
+           Ustrcmp(argv[i], "environment") == 0))
         {
         readconf_print(argv[i+1], argv[i], flag_n);
         i++;