]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.3-20060405
authorWietse Venema <wietse@porcupine.org>
Wed, 5 Apr 2006 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:32:16 +0000 (06:32 +0000)
postfix/HISTORY
postfix/src/cleanup/cleanup_message.c
postfix/src/global/mail_version.h
postfix/src/global/mime_state.c
postfix/src/global/mime_state.h
postfix/src/local/maildir.c
postfix/src/verify/verify.c
postfix/src/virtual/maildir.c

index 5f96028e918b62f9275379346da89cbe9dd65b8c..b03bee8c71c3e54244dac7efe821b2e3a3f4d425 100644 (file)
@@ -12092,6 +12092,35 @@ Apologies for any names omitted.
        Bugfix: the pipe-to-command error message was lost when the
        command could not be executed. File: global/pipe_command.c.
 
+20060404
+
+       Bugfix in sanity check: after reading a record from the
+       address verification database, a sanity check did not reject
+       a record with all-zero time stamp fields.  Such records are
+       never written; the test is there just in case something is
+       broken, so that Postfix will not blindly march on and create
+       chaos. The sanity check tested pointer values, instead of
+       dereferencing the pointers.  Found by Coverity.  File:
+       verify/verify.c.
+
+       Bugfix in sanity check: when the maildir delivery routine
+       opens an output file it looks up the file attributes via
+       the file handle it just got.  There is a sanity check that
+       detects if the attribute lookup fails, an error that never
+       happens. The code that handles the impossible error did not
+       close the output file. This would cause a virtual or local
+       delivery agent to waste up to 100 file descriptors.  But
+       for that error to happen the system would have to be so
+       sick that you would have more serious problems than a file
+       descriptor leak.  Found by Coverity.  Files: local/maildir.c,
+       virtual/maildir.c.
+
+20060405
+
+       Bugfix: the MIME parser assumed input is null terminated
+       when reporting errors. Fix by Leandro Santi. Files:
+       global/mime_state.c, cleanup/cleanup_message.c.
+
 Wish list:
 
        Don't send xforward attributes to every site that announces
index c09764d0f556567649d7ff27f195bd3f358d5c8b..52ab9c09cf6d2a11e9f552e243f453949e2e2732 100644 (file)
@@ -827,7 +827,7 @@ static void cleanup_message_headerbody(CLEANUP_STATE *state, int type,
 /* cleanup_mime_error_callback - error report call-back routine */
 
 static void cleanup_mime_error_callback(void *context, int err_code,
-                                               const char *text)
+                                             const char *text, ssize_t len)
 {
     CLEANUP_STATE *state = (CLEANUP_STATE *) context;
     const char *origin;
@@ -839,9 +839,10 @@ static void cleanup_mime_error_callback(void *context, int err_code,
     if ((err_code & ~MIME_ERR_TRUNC_HEADER) != 0) {
        if ((origin = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
            origin = MAIL_ATTR_ORG_NONE;
-       msg_info("%s: reject: mime-error %s: %.100s from %s; from=<%s> to=<%s>",
-                state->queue_id, mime_state_error(err_code), text, origin,
-                state->sender, state->recip ? state->recip : "unknown");
+#define TEXT_LEN (len < 100 ? (int) len : 100)
+       msg_info("%s: reject: mime-error %s: %.*s from %s; from=<%s> to=<%s>",
+                state->queue_id, mime_state_error(err_code), TEXT_LEN, text,
+           origin, state->sender, state->recip ? state->recip : "unknown");
     }
 }
 
index fc5b98bc3c5e2be1c6181814a5271f94906e967e..9069dcd4646eef797b69f5e6881866ab4a2d938d 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20060403"
+#define MAIL_RELEASE_DATE      "20060405"
 #define MAIL_VERSION_NUMBER    "2.3"
 
 #ifdef SNAPSHOT
index 8988ad5bbf76d28345605824cd717c2074e59f35..5727ac89831371c812183651cf2d0001afe01581 100644 (file)
@@ -391,14 +391,24 @@ static MIME_ENCODING mime_encoding_map[] = {      /* RFC 2045 */
 #define END(x)         vstring_end(x)
 #define CU_CHAR_PTR(x) ((const unsigned char *) (x))
 
-#define REPORT_ERROR(state, err_type, text) do { \
+#define REPORT_ERROR_LEN(state, err_type, text, len) do { \
        if ((state->err_flags & err_type) == 0) { \
            if (state->err_print != 0) \
-               state->err_print(state->app_context, err_type, text); \
+               state->err_print(state->app_context, err_type, text, len); \
            state->err_flags |= err_type; \
        } \
     } while (0)
 
+#define REPORT_ERROR(state, err_type, text) do { \
+       const char *_text = text; \
+       ssize_t _len = strlen(text); \
+       REPORT_ERROR_LEN(state, err_type, _text, _len); \
+    } while (0)
+
+#define REPORT_ERROR_BUF(state, err_type, buf) \
+    REPORT_ERROR_LEN(state, err_type, STR(buf), LEN(buf))
+
+
  /*
   * Outputs and state changes are interleaved, so we must maintain separate
   * offsets for header and body segments.
@@ -600,8 +610,8 @@ static void mime_state_content_type(MIME_STATE *state,
                    && state->token[1].type == '=') {
                    if (state->nesting_level > var_mime_maxdepth) {
                        if (state->static_flags & MIME_OPT_REPORT_NESTING)
-                           REPORT_ERROR(state, MIME_ERR_NESTING,
-                                        STR(state->output_buffer));
+                           REPORT_ERROR_BUF(state, MIME_ERR_NESTING,
+                                            state->output_buffer);
                    } else {
                        mime_state_push(state, def_ctype, def_stype,
                                        state->token[2].u.value);
@@ -769,8 +779,8 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
                        vstring_strncat(state->output_buffer, text, len);
                    } else {
                        if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER)
-                           REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER,
-                                        STR(state->output_buffer));
+                           REPORT_ERROR_BUF(state, MIME_ERR_TRUNC_HEADER,
+                                            state->output_buffer);
                    }
                    SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type);
                }
@@ -780,8 +790,8 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
                        vstring_strncat(state->output_buffer, text, len);
                    } else {
                        if (state->static_flags & MIME_OPT_REPORT_TRUNC_HEADER)
-                           REPORT_ERROR(state, MIME_ERR_TRUNC_HEADER,
-                                        STR(state->output_buffer));
+                           REPORT_ERROR_BUF(state, MIME_ERR_TRUNC_HEADER,
+                                            state->output_buffer);
                    }
                    SAVE_PREV_REC_TYPE_AND_RETURN_ERR_FLAGS(state, rec_type);
                }
@@ -811,8 +821,8 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
                    for (cp = CU_CHAR_PTR(STR(state->output_buffer));
                         cp < CU_CHAR_PTR(END(state->output_buffer)); cp++)
                        if (*cp & 0200) {
-                           REPORT_ERROR(state, MIME_ERR_8BIT_IN_HEADER,
-                                        STR(state->output_buffer));
+                           REPORT_ERROR_BUF(state, MIME_ERR_8BIT_IN_HEADER,
+                                            state->output_buffer);
                            break;
                        }
                }
@@ -836,7 +846,7 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
 
            /*
             * See if this input is (the beginning of) a message header.
-            *
+            * 
             * Normalize obsolete "name space colon" syntax to "name colon".
             * Things would be too confusing otherwise.
             * 
@@ -990,7 +1000,8 @@ int     mime_state_update(MIME_STATE *state, int rec_type,
                && (state->err_flags & MIME_ERR_8BIT_IN_7BIT_BODY) == 0) {
                for (cp = CU_CHAR_PTR(text); cp < CU_CHAR_PTR(text + len); cp++)
                    if (*cp & 0200) {
-                       REPORT_ERROR(state, MIME_ERR_8BIT_IN_7BIT_BODY, text);
+                       REPORT_ERROR_LEN(state, MIME_ERR_8BIT_IN_7BIT_BODY,
+                                        text, len);
                        break;
                    }
            }
@@ -1137,9 +1148,11 @@ static void body_end(void *context)
     vstream_fprintf(stream, "BODY END\n");
 }
 
-static void err_print(void *unused_context, int err_flag, const char *text)
+static void err_print(void *unused_context, int err_flag,
+                             const char *text, ssize_t len)
 {
-    msg_warn("%s: %.100s", mime_state_error(err_flag), text);
+    msg_warn("%s: %.*s", mime_state_error(err_flag),
+            len < 100 ? (int) len : 100, text);
 }
 
 int     var_header_limit = 2000;
index 952967b1180f502187f70397e17c4a93dc11e005..78454a23e3a169446500bc46747e3b6335fbebbf 100644 (file)
@@ -28,7 +28,7 @@ typedef struct MIME_STATE MIME_STATE;
 typedef void (*MIME_STATE_HEAD_OUT) (void *, int, HEADER_OPTS *, VSTRING *, off_t);
 typedef void (*MIME_STATE_BODY_OUT) (void *, int, const char *, ssize_t, off_t);
 typedef void (*MIME_STATE_ANY_END) (void *);
-typedef void (*MIME_STATE_ERR_PRINT) (void *, int, const char *);
+typedef void (*MIME_STATE_ERR_PRINT) (void *, int, const char *, ssize_t);
 
 extern MIME_STATE *mime_state_alloc(int, MIME_STATE_HEAD_OUT, MIME_STATE_ANY_END, MIME_STATE_BODY_OUT, MIME_STATE_ANY_END, MIME_STATE_ERR_PRINT, void *);
 extern int mime_state_update(MIME_STATE *, int, const char *, ssize_t);
index 08a50b43fb8970bc455f4971fdf2634d47c243f6..2860f7769e9e34f13d2d377c010fc7f32dd6259f 100644 (file)
@@ -191,8 +191,13 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
        dsb_simple(why, mbox_dsn(errno, "5.2.0"),
                   "create maildir file %s: %m", tmpfile);
     } else if (fstat(vstream_fileno(dst), &st) < 0) {
-       dsb_simple(why, mbox_dsn(errno, "5.2.0"),
-                  "create maildir file %s: %m", tmpfile);
+
+       /*
+        * Coverity 200604: file descriptor leak in code that never executes.
+        * Code replaced by msg_fatal(), as it is not worthwhile to continue
+        * after an impossible error condition.
+        */
+       msg_fatal("fstat %s: %m", tmpfile);
     } else {
        vstring_sprintf(buf, "%lu.V%lxI%lxM%lu.%s",
                        (unsigned long) starttime.tv_sec,
index 49fccbcb11f1f0f53d9040608fc0596fe2a93bc3..b656a17d1a9f71d20403612c0b27ffe6bc048a36 100644 (file)
@@ -266,11 +266,18 @@ static int verify_parse_entry(char *buf, int *status, long *probed,
        *probed = atol(probed_text);
        *updated = atol(updated_text);
        *status = atoi(buf);
+
+       /*
+        * Coverity 200604: the code incorrectly tested (probed || updated),
+        * so that the sanity check never detected all-zero time stamps. Such
+        * records are never written. If we read a record with all-zero time
+        * stamps, then something is badly broken.
+        */
        if ((*status == DEL_RCPT_STAT_OK
             || *status == DEL_RCPT_STAT_DEFER
             || *status == DEL_RCPT_STAT_BOUNCE
             || *status == DEL_RCPT_STAT_TODO)
-           && (probed || updated))
+           && (*probed || *updated))
            return (0);
     }
     msg_warn("bad address verify table entry: %.100s", buf);
index 48b7b7fa9b004c9226da80a0273c01777ff4b51d..8fcccae684fb9a7d028fa2c5d0ff420f697c461a 100644 (file)
@@ -185,8 +185,13 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr)
        dsb_simple(why, mbox_dsn(errno, "4.2.0"),
                   "create maildir file %s: %m", tmpfile);
     } else if (fstat(vstream_fileno(dst), &st) < 0) {
-       dsb_simple(why, mbox_dsn(errno, "4.2.0"),
-                  "create maildir file %s: %m", tmpfile);
+
+       /*
+        * Coverity 200604: file descriptor leak in code that never executes.
+        * Code replaced by msg_fatal(), as it is not worthwhile to continue
+        * after an impossible error condition.
+        */
+       msg_fatal("fstat %s: %m", tmpfile);
     } else {
        vstring_sprintf(buf, "%lu.V%lxI%lxM%lu.%s",
                        (unsigned long) starttime.tv_sec,