CVE-2020-28010: Heap out-of-bounds write in main()
[exim.git] / src / src / exim.c
index e1736d6e98ba68f7456f6ebdca948a9368d9c10b..975b39a5828d596f4ad6f911631143dde67ad3fd 100644 (file)
@@ -762,7 +762,7 @@ exit(EXIT_FAILURE);
 }
 
 /* fail if a length is too long */
-static void
+static inline void
 exim_len_fail_toolong(int itemlen, int maxlen, const char *description)
 {
 if (itemlen <= maxlen)
@@ -773,7 +773,7 @@ exit(EXIT_FAILURE);
 }
 
 /* only pass through the string item back to the caller if it's short enough */
-static const uschar *
+static inline const uschar *
 exim_str_fail_toolong(const uschar *item, int maxlen, const char *description)
 {
 exim_len_fail_toolong(Ustrlen(item), maxlen, description);
@@ -3207,6 +3207,10 @@ on the second character (the one after '-'), to save some effort. */
         -oPX:       delete pid file of daemon */
 
       case 'P':
+       if (!f.running_in_test_harness && real_uid != root_uid && real_uid != exim_uid)
+         exim_fail("exim: only uid=%d or uid=%d can use -oP and -oPX "
+                    "(uid=%d euid=%d | %d)\n",
+                    root_uid, exim_uid, getuid(), geteuid(), real_uid);
        if (!*argrest) override_pid_file_path = argv[++i];
        else if (Ustrcmp(argrest, "X") == 0) delete_pid_file();
        else badarg = TRUE;
@@ -3835,7 +3839,6 @@ during readconf_main() some expansion takes place already. */
 
 /* Store the initial cwd before we change directories.  Can be NULL if the
 dir has already been unlinked. */
-errno = 0;
 initial_cwd = os_getcwd(NULL, 0);
 if (!initial_cwd && errno)
   exim_fail("exim: getting initial cwd failed: %s\n", strerror(errno));
@@ -4129,11 +4132,9 @@ if (  (debug_selector & D_any  ||  LOGGING(arguments))
     p += 13;
   else
     {
-    Ustrncpy(p + 4, initial_cwd, big_buffer_size-5);
-    p += 4 + Ustrlen(initial_cwd);
-    /* in case p is near the end and we don't provide enough space for
-     * string_format to be willing to write. */
-    *p = '\0';
+    p += 4;
+    snprintf(CS p, big_buffer_size - (p - big_buffer), "%s", CCS initial_cwd);
+    p += Ustrlen(CCS p);
     }
 
   (void)string_format(p, big_buffer_size - (p - big_buffer), " %d args:", argc);