mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 14:17:41 +00:00
postfix-2.3-20060405
This commit is contained in:
committed by
Viktor Dukhovni
parent
ee4ef8eeb6
commit
4a7912c04a
@@ -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
|
||||
|
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user