]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.3.5 v2.3.5
authorWietse Venema <wietse@porcupine.org>
Mon, 11 Dec 2006 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Sat, 10 Feb 2018 20:53:22 +0000 (15:53 -0500)
postfix/HISTORY
postfix/html/bounce.5.html
postfix/man/man5/bounce.5
postfix/proto/bounce
postfix/src/bounce/bounce_cleanup.c
postfix/src/bounce/bounce_templates.c
postfix/src/global/mail_version.h
postfix/src/util/msg.c
postfix/src/util/msg_output.c
postfix/src/util/vbuf_print.c

index 9d88728898b4fb3b17c7c672c41c08fa993d7828..3f2ecad6d8ed202f041f737feda1ee34be99bdb4 100644 (file)
@@ -12845,3 +12845,20 @@ Apologies for any names omitted.
        Cleanup: when smtp_generic_maps is turned on, don't parse
        MIME structures in the message body. Victor Duchovni. File:
        smtp/smtp_proto.c.
+
+20061210
+
+       Robustness: low-cost re-entrancy guard that allows daemons
+       to call msg_fatal() etc. from a signal handler, without
+       risking memory corruption, or deadlock on Redhat Linux.
+       This works provided that the signal handler never returns.
+       In that special case we need not guarantee after-the-fact
+       consistency of the interrupted process.  File: util/msg_output.c.
+
+       Robustness: replace exit() calls by _exit(). File: util/msg.c,
+       bounce/bounce_cleanup.c.
+
+       Cleanup: document under what conditions these protections
+       work, with REENTRANCY sections in the relevant man pages.
+       Files: util/vbuf.c.  util/msg.c, util/msg_output.c.
+
index 7d5ebac31f2179104ca08a317482f5dd09a3ca0b..e6c23320c514d62f2897d4397dbc1bd46f728c94 100644 (file)
@@ -81,7 +81,7 @@ BOUNCE(5)                                                            BOUNCE(5)
            I'm sorry to have to inform you that your message could not
            be delivered to one or more recipients. It's attached below.
 
-           For further assistance, please send mail to &lt;postmaster&gt;
+           For further assistance, please send mail to postmaster.
 
            If you do so, please include this problem report. You can
            delete your own text from the attached returned message.
index ce3d037357de87356027cb5861885f24fba745bf..4c6215ab319720a14ed014534b38a59b2c9d2f3f 100644 (file)
@@ -91,7 +91,7 @@ This is the mail system at host $myhostname.
 I'm sorry to have to inform you that your message could not
 be delivered to one or more recipients. It's attached below.
 
-For further assistance, please send mail to <postmaster>
+For further assistance, please send mail to postmaster.
 
 If you do so, please include this problem report. You can
 delete your own text from the attached returned message.
index f770a5e33e569aa9c5927344babad657f5c3bf6c..842cad9b8dfecc376e6d503a50ce5aea4f82ce14 100644 (file)
@@ -81,7 +81,7 @@
 #      I'm sorry to have to inform you that your message could not
 #      be delivered to one or more recipients. It's attached below.
 #      
-#      For further assistance, please send mail to <postmaster>
+#      For further assistance, please send mail to postmaster.
 #      
 #      If you do so, please include this problem report. You can
 #      delete your own text from the attached returned message.
index a68850a5b533ca0554c7e04fd1eba3f9d96ce715..9fb900bb0abcbedf5c5b06286840dc7b55483661 100644 (file)
@@ -129,7 +129,7 @@ static void bounce_cleanup_sig(int sig)
      */
     if (bounce_cleanup_path)
        (void) unlink(vstring_str(bounce_cleanup_path));
-    exit(sig);
+    _exit(sig);
 }
 
 /* bounce_cleanup_register - register logfile to clean up */
index cf4ce98b1157e8bc8e6be9390eebc20e634213d4..cdea765d22badfefc79c7434f2cbaa3b8371988d 100644 (file)
@@ -98,7 +98,7 @@ static const char *def_bounce_failure_body[] = {
     "I'm sorry to have to inform you that your message could not",
     "be delivered to one or more recipients. It's attached below.",
     "",
-    "For further assistance, please send mail to " MAIL_ADDR_POSTMASTER,
+    "For further assistance, please send mail to " MAIL_ADDR_POSTMASTER ".",
     "",
     "If you do so, please include this problem report. You can",
     "delete your own text from the attached returned message.",
@@ -134,7 +134,7 @@ static const char *def_bounce_delay_body[] = {
     ,
     "It will be retried until it is $maximal_queue_lifetime_days day(s) old.",
     "",
-    "For further assistance, please send mail to " MAIL_ADDR_POSTMASTER,
+    "For further assistance, please send mail to " MAIL_ADDR_POSTMASTER ".",
     "",
     "If you do so, please include this problem report. You can",
     "delete your own text from the attached returned message.",
index 2e1d3093c5726e9e6e9061d4b77c510fed9737fb..73a4cff0cd92c1242acb0128296ffc81c69e8e87 100644 (file)
@@ -20,8 +20,8 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20061208"
-#define MAIL_VERSION_NUMBER    "2.3.5-RC2"
+#define MAIL_RELEASE_DATE      "20061211"
+#define MAIL_VERSION_NUMBER    "2.3.5"
 
 #ifdef SNAPSHOT
 # define MAIL_VERSION_DATE     "-" MAIL_RELEASE_DATE
index 3aac0197652ae1ee382923b052e179864b8b6120..ae7798017184850c9db6529d9d06ccde22a36c3e 100644 (file)
@@ -39,7 +39,7 @@
 /*     to the standard error stream, but the disposition can be changed
 /*     by the user. See the hints below in the SEE ALSO section.
 /*
-/*     msg_info(), msg_warn(), msg_error(), msg_fatal() and msg_panic()
+/*     msg_info(), msg_warn(), msg_error(), msg_fatal*() and msg_panic()
 /*     produce a one-line record with the program name, a severity code
 /*     (except for msg_info()), and an informative message. The program
 /*     name must have been set by calling one of the msg_XXX_init()
 /*     msg_verbose is a global flag that can be set to make software
 /*     more verbose about what it is doing. By default the flag is zero.
 /*     By convention, a larger value means more noise.
+/* REENTRANCY
+/* .ad
+/* .fi
+/*     The msg_info() etc. output routines are protected against
+/*     ordinary recursive calls and against re-entry by signal
+/*     handlers.
+/*
+/*     Protection against re-entry by signal handlers is subject
+/*     to the following limitations:
+/* .IP \(bu
+/*     The signal handlers must never return. In other words, the
+/*     signal handlers must do one or more of the following: call
+/*     _exit(), kill the process with a signal, and permanently block
+/*     the process.
+/* .IP \(bu
+/*     The signal handlers must invoke msg_info() etc. not until
+/*     after the msg_XXX_init() functions complete initialization,
+/*     and not until after the first formatted output to a VSTRING
+/*     or VSTREAM.
+/* .IP \(bu
+/*     Each msg_cleanup() call-back function, and each Postfix or
+/*     system function invoked by that call-back function, either
+/*     protects itself against recursive calls and re-entry by a
+/*     terminating signal handler, or is called exclusively by the
+/*     msg(3) module.
+/* .PP
+/*     When re-entrancy is detected, the requested output and
+/*     optional cleanup operations are skipped. Skipping the output
+/*     operations prevents memory corruption of VSTREAM_ERR data
+/*     structures, and prevents deadlock on Linux releases that
+/*     use mutexes within system library routines such as syslog().
+/*     This protection exists under the condition that these
+/*     specific resources are accessed exclusively via the msg_info()
+/*     etc.  functions.
 /* SEE ALSO
 /*     msg_output(3) specify diagnostics disposition
 /*     msg_stdio(3) direct diagnostics to standard I/O stream
 int     msg_verbose = 0;
 
  /*
-  * Private state. The msg_exiting flag prevents us from recursively
-  * reporting an error.
+  * Private state.
   */
 static MSG_CLEANUP_FN msg_cleanup_fn = 0;
-static int msg_exiting = 0;
 static int msg_error_count = 0;
 static int msg_error_bound = 13;
 
+ /*
+  * The msg_exiting flag prevents us from recursively reporting an error with
+  * msg_fatal*() or msg_panic(), and provides a first-level safety net for
+  * optional cleanup actions against signal handler re-entry problems. Note
+  * that msg_vprintf() implements its own guard against re-entry.
+  * 
+  * XXX We specify global scope, to discourage the compiler from doing smart
+  * things.
+  */
+volatile int msg_exiting = 0;
+
 /* msg_info - report informative message */
 
 void    msg_info(const char *fmt,...)
@@ -175,7 +218,8 @@ NORETURN msg_fatal(const char *fmt,...)
            msg_cleanup_fn();
     }
     sleep(1);
-    exit(1);
+    /* In case we're running as a signal handler. */
+    _exit(1);
 }
 
 /* msg_fatal_status - report error and terminate gracefully */
@@ -192,7 +236,8 @@ NORETURN msg_fatal_status(int status, const char *fmt,...)
            msg_cleanup_fn();
     }
     sleep(1);
-    exit(status);
+    /* In case we're running as a signal handler. */
+    _exit(status);
 }
 
 /* msg_panic - report error and dump core */
@@ -208,7 +253,8 @@ NORETURN msg_panic(const char *fmt,...)
     }
     sleep(1);
     abort();                                   /* Die! */
-    exit(1);                                   /* DIE!! */
+    /* In case we're running as a signal handler. */
+    _exit(1);                                  /* DIE!! */
 }
 
 /* msg_cleanup - specify cleanup routine */
index 889206bdb1c2fc8343264a987754da54f28f4e77..ebef3c6cf6756fccd8e5a729ed34817c5355c2e3 100644 (file)
 /*
 /*     msg_text() copies a pre-formatted text, sanitizes the result, and
 /*     calls the output handlers registered with msg_output().
+/* REENTRANCY
+/* .ad
+/* .fi
+/*     The above output routines are protected against ordinary
+/*     recursive calls and against re-entry by signal
+/*     handlers, with the following limitations:
+/* .IP \(bu
+/*     The signal handlers must never return. In other words, the
+/*     signal handlers must do one or more of the following: call
+/*     _exit(), kill the process with a signal, and permanently
+/*     block the process.
+/* .IP \(bu
+/*     The signal handlers must call the above output routines not
+/*     until after msg_output() completes initialization, and not
+/*     until after the first formatted output to a VSTRING or
+/*     VSTREAM.
+/* .IP \(bu
+/*     Each msg_output() call-back function, and each Postfix or
+/*     system function called by that call-back function, either
+/*     must protect itself against recursive calls and re-entry
+/*     by a terminating signal handler, or it must be called
+/*     exclusively by functions in the msg_output(3) module.
+/* .PP
+/*     When re-entrancy is detected, the requested output operation
+/*     is skipped. This prevents memory corruption of VSTREAM_ERR
+/*     data structures, and prevents deadlock on Linux releases
+/*     that use mutexes within system library routines such as
+/*     syslog(). This protection exists under the condition that
+/*     these specific resources are accessed exclusively via
+/*     msg_output() call-back functions.
 /* LICENSE
 /* .ad
 /* .fi
 #include <percentm.h>
 #include <msg_output.h>
 
+ /*
+  * Global scope, to discourage the compiler from doing smart things.
+  */
+volatile int msg_vprintf_lock;
+volatile int msg_text_lock;
+
  /*
   * Private state.
   */
@@ -79,6 +115,12 @@ static VSTRING *msg_buffer = 0;
 void    msg_output(MSG_OUTPUT_FN output_fn)
 {
 
+    /*
+     * Allocate all resources during initialization.
+     */
+    if (msg_buffer == 0)
+       msg_buffer = vstring_alloc(100);
+
     /*
      * We're not doing this often, so avoid complexity and allocate memory
      * for an exact fit.
@@ -106,10 +148,13 @@ void    msg_printf(int level, const char *format,...)
 
 void    msg_vprintf(int level, const char *format, va_list ap)
 {
-    if (msg_buffer == 0)
-       msg_buffer = vstring_alloc(100);
-    vstring_vsprintf(msg_buffer, percentm(format, errno), ap);
-    msg_text(level, vstring_str(msg_buffer));
+    if (msg_vprintf_lock == 0) {
+       msg_vprintf_lock = 1;
+       /* OK if terminating signal handler hijacks control before next stmt. */
+       vstring_vsprintf(msg_buffer, percentm(format, errno), ap);
+       msg_text(level, vstring_str(msg_buffer));
+       msg_vprintf_lock = 0;
+    }
 }
 
 /* msg_text - sanitize and log pre-formatted text */
@@ -121,13 +166,17 @@ void    msg_text(int level, const char *text)
     /*
      * Sanitize the text. Use a private copy if necessary.
      */
-    if (msg_buffer == 0)
-       msg_buffer = vstring_alloc(100);
-    if (text != vstring_str(msg_buffer))
-       vstring_strcpy(msg_buffer, text);
-    printable(vstring_str(msg_buffer), '?');
-    if (msg_output_fn_count == 0)
-       msg_vstream_init("unknown", VSTREAM_ERR);
-    for (i = 0; i < msg_output_fn_count; i++)
-       msg_output_fn[i] (level, vstring_str(msg_buffer));
+    if (msg_text_lock == 0) {
+       msg_text_lock = 1;
+       /* OK if terminating signal handler hijacks control before next stmt. */
+       if (text != vstring_str(msg_buffer))
+           vstring_strcpy(msg_buffer, text);
+       printable(vstring_str(msg_buffer), '?');
+       /* On-the-fly initialization for debugging test programs only. */
+       if (msg_output_fn_count == 0)
+           msg_vstream_init("unknown", VSTREAM_ERR);
+       for (i = 0; i < msg_output_fn_count; i++)
+           msg_output_fn[i] (level, vstring_str(msg_buffer));
+       msg_text_lock = 0;
+    }
 }
index e64b15b2e60068a6c57132cdd95d4dd638cbf400..8b9878d33a799552c8ff138e41e69f2c2695abd3 100644 (file)
 /*     In addition, vbuf_print() recognizes the %m format specifier
 /*     and expands it to the error message corresponding to the current
 /*     value of the global \fIerrno\fR variable.
+/* REENTRANCY
+/* .ad
+/* .fi
+/*     vbuf_print() allocates a static buffer. After completion
+/*     of the first vbuf_print() call, this buffer is safe for
+/*     reentrant vbuf_print() calls by (asynchronous) terminating
+/*     signal handlers or by (synchronous) terminating error
+/*     handlers. vbuf_print() initialization typically happens
+/*     upon the first formatted output to a VSTRING or VSTREAM.
+/*
+/*     However, it is up to the caller to ensure that the destination
+/*     VSTREAM or VSTRING buffer is protected against reentrant usage.
 /* LICENSE
 /* .ad
 /* .fi