]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.3.20 v3.3.20
authorWietse Venema <wietse@porcupine.org>
Sun, 7 Nov 2021 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Mon, 8 Nov 2021 13:34:09 +0000 (08:34 -0500)
postfix/HISTORY
postfix/src/cleanup/cleanup_body_edit.c
postfix/src/cleanup/cleanup_milter.c
postfix/src/global/mail_version.h
postfix/src/milter/milter.h
postfix/src/milter/milter8.c
postfix/src/postconf/postconf_builtin.c
postfix/src/smtpd/smtpd_check.c
postfix/src/tls/tls_misc.c

index 00f3b02a42165e16e3d9580c3a5a0068b34f3d77..a39180266f314bc2258991d5c01f59c3cbd33c40 100644 (file)
@@ -23783,3 +23783,71 @@ Apologies for any names omitted.
        was comparing memory addresses instead of queue file names.
        It now properly compares strings. Reported by Mehmet Avcioglu.
        File: global/record.c.
+
+20210811
+
+       Bitrot: OpenSSL 3.x requires const. File: tls/tls_misc.c.
+
+20210925
+
+       Bugfix (bug introduced: Postfix 2.10): postconf -x produced
+       incorrect output, because different functions were implicitly
+       sharing a buffer for intermediate results. Reported
+       by raf, root cause analysis by Viktor Dukhovni. File:
+       postconf/postconf_builtin.c.
+
+20211030
+
+       Bugfix (problem introduced: Postfix 2.11): check_ccert_access
+       worked as expected, but produced a spurious warning when
+       Postfix was built without SASL support. Fix by Brad Barden.
+       File: smtpd/smtpd_check.c.
+
+20211105
+
+       Bugfix (introduced: Postfix 2.4): queue file corruption
+       after a Milter (for example, MIMEDefang) made a request to
+       replace the message body with a copy of that message body
+       plus additional text (for example, a SpamAssassin report).
+
+       The most likely impacts were a) the queue manager reporting
+       a fatal error resulting in email delivery delays, or b) the
+       queue manager reporting the corruption and moving the message
+       to the corrupt queue for damaged messages.
+
+       However, a determined adversary could craft an email message
+       that would trigger the bug, and insert a content filter
+       destination or a redirect email address into its queue file.
+       Postfix would then deliver the message headers there, in
+       most cases without delivering the message body. With enough
+       experimentation, an attacker could make Postfix deliver
+       both the message headers and body.
+
+       The details of a successful attack depend on the Milter
+       implementation, and on the Postfix and Milter configuration
+       details; these can be determined remotely through
+       experimentation.  Failed experiments may be detected when
+       the queue manager terminates with a fatal error, or when
+       the queue manager moves damaged files to the "corrupt" queue
+       as evidence.
+
+       Technical details: when Postfix executes a "replace body"
+       Milter request it will reuse queue file storage that was
+       used by the existing email message body. If the new body
+       is larger, Postfix will append body content to the end of
+       the queue file. The corruption happened when a Milter (for
+       example, MIMEDefang) made a request to replace the body of
+       a message with a new body that contained a copy of the
+       original body plus some new text, and the original body
+       contained a line longer than $line_length_limit bytes (for
+       example, an image encoded in base64 without hard or soft
+       line breaks). In queue files, Postfix stores a long text
+       line as multiple records with up to $line_length_limit bytes
+       each. Unfortunately, Postfix's "replace body" support did
+       not account for the additional queue file space needed to
+       store the second etc.  record headers. And thus, the last
+       record(s) of a long text line could overwrite one or more
+       queue file records immediately after the space that was
+       previously occupied by the original message body.
+
+       Problem report by BenoĆ®t Panizzon.
index 93eadae0b82542d36491ff4c8254b1d4ea6f7732..2fff1bcadd4788a92ce4c81daac3d37a6b35be90 100644 (file)
@@ -207,7 +207,7 @@ int     cleanup_body_edit_write(CLEANUP_STATE *state, int rec_type,
     /*
      * Finally, output the queue file record.
      */
-    CLEANUP_OUT_BUF(state, REC_TYPE_NORM, buf);
+    CLEANUP_OUT_BUF(state, rec_type, buf);
     curr_rp->write_offs = vstream_ftell(state->dst);
 
     return (0);
index ee633da0017acfe7e28d4f2de6b1e5d3df7f2140..f2f585f42f89ac8195ff8f82808a9a36696a9a4a 100644 (file)
@@ -1831,7 +1831,8 @@ static const char *cleanup_del_rcpt(void *context, const char *ext_rcpt)
 
 /* cleanup_repl_body - replace message body */
 
-static const char *cleanup_repl_body(void *context, int cmd, VSTRING *buf)
+static const char *cleanup_repl_body(void *context, int cmd, int rec_type,
+                                            VSTRING *buf)
 {
     const char *myname = "cleanup_repl_body";
     CLEANUP_STATE *state = (CLEANUP_STATE *) context;
@@ -1843,7 +1844,7 @@ static const char *cleanup_repl_body(void *context, int cmd, VSTRING *buf)
      */
     switch (cmd) {
     case MILTER_BODY_LINE:
-       if (cleanup_body_edit_write(state, REC_TYPE_NORM, buf) < 0)
+       if (cleanup_body_edit_write(state, rec_type, buf) < 0)
            return (cleanup_milter_error(state, errno));
        break;
     case MILTER_BODY_START:
index 85bc6fde50f78e7f449d6185d75d5a791dcafdeb..569cf64cb8213d4e48a0b8dac950800d39f74cdc 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      "20210724"
-#define MAIL_VERSION_NUMBER    "3.3.19"
+#define MAIL_RELEASE_DATE      "20211107"
+#define MAIL_VERSION_NUMBER    "3.3.20"
 
 #ifdef SNAPSHOT
 #define MAIL_VERSION_DATE      "-" MAIL_RELEASE_DATE
index 951744fdb1c1f941d0fb4bab965a2e0ba5a7d837..601adf4cf38a4fb2917e71e8c73f0974bcb2b2cc 100644 (file)
@@ -100,7 +100,7 @@ typedef const char *(*MILTER_DEL_HEADER_FN) (void *, ssize_t, const char *);
 typedef const char *(*MILTER_EDIT_FROM_FN) (void *, const char *, const char *);
 typedef const char *(*MILTER_EDIT_RCPT_FN) (void *, const char *);
 typedef const char *(*MILTER_EDIT_RCPT_PAR_FN) (void *, const char *, const char *);
-typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, VSTRING *);
+typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, int, VSTRING *);
 
 typedef struct MILTERS {
     MILTER *milter_list;               /* linked list of Milters */
index 317e55152c26d2a72db04fe7527b07ca3472b8e9..46badb3660ae7a897593d455abb6928d8190312f 100644 (file)
@@ -1145,10 +1145,12 @@ static const char *milter8_event(MILTER8 *milter, int event,
            if (edit_resp == 0 && LEN(body_line_buf) > 0)
                edit_resp = parent->repl_body(parent->chg_context,
                                              MILTER_BODY_LINE,
+                                             REC_TYPE_NORM,
                                              body_line_buf);
            if (edit_resp == 0)
                edit_resp = parent->repl_body(parent->chg_context,
                                              MILTER_BODY_END,
+                                             /* unused*/ 0,
                                              (VSTRING *) 0);
            body_edit_lockout = 1;
            vstring_free(body_line_buf);
@@ -1544,6 +1546,7 @@ static const char *milter8_event(MILTER8 *milter, int event,
                        body_line_buf = vstring_alloc(var_line_limit);
                        edit_resp = parent->repl_body(parent->chg_context,
                                                      MILTER_BODY_START,
+                                                     /* unused */ 0,
                                                      (VSTRING *) 0);
                    }
                    /* Extract lines from the on-the-wire CRLF format. */
@@ -1557,9 +1560,18 @@ static const char *milter8_event(MILTER8 *milter, int event,
                                                 LEN(body_line_buf) - 1);
                            edit_resp = parent->repl_body(parent->chg_context,
                                                          MILTER_BODY_LINE,
+                                                         REC_TYPE_NORM,
                                                          body_line_buf);
                            VSTRING_RESET(body_line_buf);
                        } else {
+                           /* Preserves \r if not followed by \n. */
+                           if (LEN(body_line_buf) == var_line_limit) {
+                               edit_resp = parent->repl_body(parent->chg_context,
+                                                          MILTER_BODY_LINE,
+                                                             REC_TYPE_CONT,
+                                                             body_line_buf);
+                               VSTRING_RESET(body_line_buf);
+                           }
                            VSTRING_ADDCH(body_line_buf, ch);
                        }
                    }
index a673df134af08b4fb627293c0d338548859d831a..e1a55faf560e8640b312028af5af2f4f6a93485d 100644 (file)
@@ -244,6 +244,7 @@ static const char *pcf_check_mydomainname(void)
 static const char *pcf_mynetworks(void)
 {
     static const char *networks;
+    VSTRING *exp_buf;
     const char *junk;
 
     /*
@@ -252,10 +253,12 @@ static const char *pcf_mynetworks(void)
     if (networks)
        return (networks);
 
+    exp_buf = vstring_alloc(100);
+
     if (var_inet_interfaces == 0) {
        if ((pcf_cmd_mode & PCF_SHOW_DEFS)
            || (junk = mail_conf_lookup_eval(VAR_INET_INTERFACES)) == 0)
-           junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+           junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
                                              DEF_INET_INTERFACES,
                                              (PCF_MASTER_ENT *) 0);
        var_inet_interfaces = mystrdup(junk);
@@ -263,7 +266,7 @@ static const char *pcf_mynetworks(void)
     if (var_mynetworks_style == 0) {
        if ((pcf_cmd_mode & PCF_SHOW_DEFS)
            || (junk = mail_conf_lookup_eval(VAR_MYNETWORKS_STYLE)) == 0)
-           junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+           junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
                                              DEF_MYNETWORKS_STYLE,
                                              (PCF_MASTER_ENT *) 0);
        var_mynetworks_style = mystrdup(junk);
@@ -271,12 +274,13 @@ static const char *pcf_mynetworks(void)
     if (var_inet_protocols == 0) {
        if ((pcf_cmd_mode & PCF_SHOW_DEFS)
            || (junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)) == 0)
-           junk = pcf_expand_parameter_value((VSTRING *) 0, pcf_cmd_mode,
+           junk = pcf_expand_parameter_value(exp_buf, pcf_cmd_mode,
                                              DEF_INET_PROTOCOLS,
                                              (PCF_MASTER_ENT *) 0);
        var_inet_protocols = mystrdup(junk);
        (void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
     }
+    vstring_free(exp_buf);
     return (networks = mystrdup(mynetworks()));
 }
 
index 73ee5b48fc9b2e9bf1d6e1ee37e44ca9708df35f..4862cd4143a0a333a942c9471e3afdff391a9de8 100644 (file)
@@ -4246,8 +4246,8 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
            }
        } else if (is_map_command(state, name, CHECK_CCERT_ACL, &cpp)) {
            status = check_ccert_access(state, *cpp, def_acl);
-#ifdef USE_SASL_AUTH
        } else if (is_map_command(state, name, CHECK_SASL_ACL, &cpp)) {
+#ifdef USE_SASL_AUTH
            if (var_smtpd_sasl_enable) {
                if (state->sasl_username && state->sasl_username[0])
                    status = check_sasl_access(state, *cpp, def_acl);
index 0673ff89f74a56924b4bb16ea56cdf0ec4dd1d23..2ad1a26ee6c840adf107882ccb86d80a2e3a8a9a 100644 (file)
@@ -877,7 +877,7 @@ void    tls_get_signature_params(TLS_SESS_STATE *TLScontext)
     EVP_PKEY *pkey = 0;
 
 #ifndef OPENSSL_NO_EC
-    EC_KEY *eckey;
+    const EC_KEY *eckey;
 
 #endif