diff --git a/postfix/HISTORY b/postfix/HISTORY index e443a8627..3824d470b 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -25919,3 +25919,13 @@ Apologies for any names omitted. Additional postcat flags for debuging a corrupted queue file (-s: skip to offset; -r: don't follow pointer records). File: postcat/postcat.c. + +20211110 + + Minor edits of 20211107 postcat changes. File: postcat.c. + + Regression prevention: added sanity check in the queue file + editing code. File: cleanup/cleanup_body_edit.c + + Regression prevention: copied a queue file record typecheck + from the pickup daemon. Files: *qmgr/qmgr_message.c. diff --git a/postfix/WISHLIST b/postfix/WISHLIST index 9bbb46f43..0985ec034 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -1,7 +1,7 @@ Wish list: - Fix the body_edit_lockout safety: turn it on when editing, - and turn if off when done. + proxy_read_maps needs a dedicated matcher that looks + inside pipemap:{}. Maybe steal some code from postconf. Add a pointer to http://mmogilvi.users.sourceforge.net/software/oauthbearer.html diff --git a/postfix/html/postcat.1.html b/postfix/html/postcat.1.html index 2928522d8..1a5c7af1d 100644 --- a/postfix/html/postcat.1.html +++ b/postfix/html/postcat.1.html @@ -55,12 +55,14 @@ POSTCAT(1) POSTCAT(1) -r Print records in file order, don't follow pointer records. - This feature is available in Postfix 3.7 and later. IP "-s off- - set" Skip to the specified queue file offset. + This feature is available in Postfix 3.7 and later. - This feature is available in Postfix 2.0 and later. + -s offset + Skip to the specified queue file offset. - -v Enable verbose logging for debugging purposes. Multiple -v + This feature is available in Postfix 3.7 and later. + + -v Enable verbose logging for debugging purposes. Multiple -v options make the software increasingly verbose. DIAGNOSTICS @@ -71,19 +73,19 @@ POSTCAT(1) POSTCAT(1) Directory with Postfix configuration files. CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant to this pro- + The following main.cf parameters are especially relevant to this pro- gram. - The text below provides only a parameter summary. See postconf(5) for + The text below provides only a parameter summary. See postconf(5) for more details including examples. config_directory (see 'postconf -d' output) - The default location of the Postfix main.cf and master.cf con- + The default location of the Postfix main.cf and master.cf con- figuration files. import_environment (see 'postconf -d' output) - The list of environment parameters that a privileged Postfix - process will import from a non-Postfix parent process, or + The list of environment parameters that a privileged Postfix + process will import from a non-Postfix parent process, or name=value environment overrides. queue_directory (see 'postconf -d' output) diff --git a/postfix/man/man1/postcat.1 b/postfix/man/man1/postcat.1 index 78c7521fc..eb3025ba1 100644 --- a/postfix/man/man1/postcat.1 +++ b/postfix/man/man1/postcat.1 @@ -56,10 +56,10 @@ This feature is available in Postfix 2.0 and later. Print records in file order, don't follow pointer records. This feature is available in Postfix 3.7 and later. -IP "\fB-s \fIoffset\fR" +.IP "\fB\-s \fIoffset\fR" Skip to the specified queue file offset. -This feature is available in Postfix 2.0 and later. +This feature is available in Postfix 3.7 and later. .IP \fB\-v\fR Enable verbose logging for debugging purposes. Multiple \fB\-v\fR options make the software increasingly verbose. diff --git a/postfix/src/cleanup/cleanup_body_edit.c b/postfix/src/cleanup/cleanup_body_edit.c index 2fff1bcad..3d4e8668b 100644 --- a/postfix/src/cleanup/cleanup_body_edit.c +++ b/postfix/src/cleanup/cleanup_body_edit.c @@ -210,6 +210,13 @@ int cleanup_body_edit_write(CLEANUP_STATE *state, int rec_type, CLEANUP_OUT_BUF(state, rec_type, buf); curr_rp->write_offs = vstream_ftell(state->dst); + /* + * Sanity check. + */ + if (curr_rp->len > 0 + && curr_rp->write_offs > curr_rp->start + curr_rp->len) + msg_panic("%s: write past end of body segment", myname); + return (0); } diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index b74f005e5..0ca8b7734 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20211107" +#define MAIL_RELEASE_DATE "20211113" #define MAIL_VERSION_NUMBER "3.7" #ifdef SNAPSHOT diff --git a/postfix/src/oqmgr/qmgr_message.c b/postfix/src/oqmgr/qmgr_message.c index ea5561561..96409ceb7 100644 --- a/postfix/src/oqmgr/qmgr_message.c +++ b/postfix/src/oqmgr/qmgr_message.c @@ -324,6 +324,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message) char *dsn_orcpt = 0; int n; int have_log_client_attr = 0; + static const char env_rec_types[] = REC_TYPE_ENVELOPE REC_TYPE_EXTRACT; + static const char extra_rec_type[] = {REC_TYPE_XTRA, 0}; + const char *expected_rec_types; /* * Initialize. No early returns or we have a memory leak. @@ -371,12 +374,14 @@ static int qmgr_message_read(QMGR_MESSAGE *message) * mailing lists. */ for (;;) { + expected_rec_types = env_rec_types; if ((curr_offset = vstream_ftell(message->fp)) < 0) msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp)); if (curr_offset == message->data_offset && curr_offset > 0) { if (vstream_fseek(message->fp, message->data_size, SEEK_CUR) < 0) msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp)); curr_offset += message->data_size; + expected_rec_types = extra_rec_type; } rec_type = rec_get_raw(message->fp, buf, 0, REC_FLAG_NONE); start = vstring_str(buf); @@ -393,6 +398,12 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->queue_id); break; } + if (strchr(expected_rec_types, rec_type) == 0) { + msg_warn("Unexpected record type '%c' at offset %ld", + rec_type, (long) curr_offset); + rec_type = REC_TYPE_ERROR; + break; + } if (rec_type == REC_TYPE_END) { message->rflags |= QMGR_READ_FLAG_SEEN_ALL_NON_RCPT; break; @@ -406,7 +417,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) */ if (rec_type == REC_TYPE_ATTR) { if ((error_text = split_nameval(start, &name, &value)) != 0) { - msg_warn("%s: ignoring bad attribute: %s: %.200s", + msg_warn("%s: bad attribute record: %s: %.200s", message->queue_id, error_text, start); rec_type = REC_TYPE_ERROR; break; diff --git a/postfix/src/postcat/postcat.c b/postfix/src/postcat/postcat.c index 2a8257965..9411f9e26 100644 --- a/postfix/src/postcat/postcat.c +++ b/postfix/src/postcat/postcat.c @@ -46,14 +46,14 @@ /* of taking the names literally. /* /* This feature is available in Postfix 2.0 and later. -/*.IP \fB-r\fR +/* .IP \fB-r\fR /* Print records in file order, don't follow pointer records. /* /* This feature is available in Postfix 3.7 and later. -/* IP "\fB-s \fIoffset\fR" +/* .IP "\fB-s \fIoffset\fR" /* Skip to the specified queue file offset. /* -/* This feature is available in Postfix 2.0 and later. +/* This feature is available in Postfix 3.7 and later. /* .IP \fB-v\fR /* Enable verbose logging for debugging purposes. Multiple \fB-v\fR /* options make the software increasingly verbose. @@ -204,8 +204,7 @@ static void postcat(VSTREAM *fp, VSTRING *buffer, int flags) /* * See if this is a plausible file. */ - if (start_offset == 0 && (flags & PC_FLAG_RAW) == 0 - && (ch = VSTREAM_GETC(fp)) != VSTREAM_EOF) { + if (start_offset == 0 && (ch = VSTREAM_GETC(fp)) != VSTREAM_EOF) { if (!strchr(REC_TYPE_ENVELOPE, ch)) { msg_warn("%s: input is not a valid queue file", VSTREAM_PATH(fp)); return; @@ -519,7 +518,7 @@ int main(int argc, char **argv) flags |= PC_FLAG_RAW; break; case 's': - if (!alldig(optarg) || (start_offset = atol(optarg)) <= 0) + if (!alldig(optarg) || (start_offset = atol(optarg)) < 0) msg_fatal("bad offset: %s", optarg); break; case 'v': diff --git a/postfix/src/qmgr/qmgr_message.c b/postfix/src/qmgr/qmgr_message.c index 02a739111..8b5631d41 100644 --- a/postfix/src/qmgr/qmgr_message.c +++ b/postfix/src/qmgr/qmgr_message.c @@ -347,6 +347,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message) char *dsn_orcpt = 0; int n; int have_log_client_attr = 0; + static const char env_rec_types[] = REC_TYPE_ENVELOPE REC_TYPE_EXTRACT; + static const char extra_rec_type[] = {REC_TYPE_XTRA, 0}; + const char *expected_rec_types; /* * Initialize. No early returns or we have a memory leak. @@ -411,12 +414,14 @@ static int qmgr_message_read(QMGR_MESSAGE *message) * mailing lists. */ for (;;) { + expected_rec_types = env_rec_types; if ((curr_offset = vstream_ftell(message->fp)) < 0) msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp)); if (curr_offset == message->data_offset && curr_offset > 0) { if (vstream_fseek(message->fp, message->data_size, SEEK_CUR) < 0) msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp)); curr_offset += message->data_size; + expected_rec_types = extra_rec_type; } rec_type = rec_get_raw(message->fp, buf, 0, REC_FLAG_NONE); start = vstring_str(buf); @@ -433,6 +438,12 @@ static int qmgr_message_read(QMGR_MESSAGE *message) message->queue_id); break; } + if (strchr(expected_rec_types, rec_type) == 0) { + msg_warn("Unexpected record type '%c' at offset %ld", + rec_type, (long) curr_offset); + rec_type = REC_TYPE_ERROR; + break; + } if (rec_type == REC_TYPE_END) { message->rflags |= QMGR_READ_FLAG_SEEN_ALL_NON_RCPT; break; @@ -446,7 +457,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message) */ if (rec_type == REC_TYPE_ATTR) { if ((error_text = split_nameval(start, &name, &value)) != 0) { - msg_warn("%s: ignoring bad attribute: %s: %.200s", + msg_warn("%s: bad attribute record: %s: %.200s", message->queue_id, error_text, start); rec_type = REC_TYPE_ERROR; break;