diff --git a/postfix/HISTORY b/postfix/HISTORY index 22ed7df49..3d37b06f2 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -24411,3 +24411,29 @@ Apologies for any names omitted. calls. This allows tlsproxy(8) to reset an I/O timer after each event without having to make an nbbio_disable_readwrite() call. Files: util/nbbio.c, tlsproxy/tlsproxy.c. + +20191013 + + Cleanup: code pattern ENFORCING_SIZE_LIMIT() for more + consistent enforcement of the 'no size limit' case (it now + requires "> 0" where previous code used "!= 0" or "> 0"). + More relevant, this explicit pattern will help finding code + that does not implement the 'no size limit' case with + var_message_limit, etc. Files: cleanup/cleanup_init.c, + local/local.c, postdrop/postdrop.c, postscreen/postscreen_smtpd.c, + sendmail/sendmail.c, smtpd/smtpd.c, smtpd/smtpd_check.c, + util/netstring.c, util/sys_defs.h, virtual/virtual.c. + + Cleanup; with message_size_limit>0, local(8) and virtual(8) + mailbox size limit checks would produce a misleading error + message when the mailbox size was unlimited. Files: + local/local.c, virtual/virtual.c. + + Cleanup: queue_minfree changed from 'int' to 'long'. File: + global/mail_params.h, src/smtpd/smtpd.c. + + Attribution: updated AUTHOR in file headers. Files: + global/bounce_log.c, global/deliver_request.h, smtp/smtp_chat.c, + smtp/smtp_rcpt.c, tls/tls_certkey.c, util/nbbio.c, + util/vstream_tweak.c. + diff --git a/postfix/src/cleanup/cleanup_init.c b/postfix/src/cleanup/cleanup_init.c index e411992d6..d0af95477 100644 --- a/postfix/src/cleanup/cleanup_init.c +++ b/postfix/src/cleanup/cleanup_init.c @@ -447,7 +447,7 @@ void cleanup_post_jail(char *unused_name, char **unused_argv) * really low limit, the difference is going to matter only when a queue * file has lots of recipients. */ - if (var_message_limit > 0) + if (ENFORCING_SIZE_LIMIT(var_message_limit)) set_file_limit((off_t) var_message_limit); /* diff --git a/postfix/src/global/bounce_log.c b/postfix/src/global/bounce_log.c index 198f2405d..b97515e1b 100644 --- a/postfix/src/global/bounce_log.c +++ b/postfix/src/global/bounce_log.c @@ -78,6 +78,11 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ /* System library. */ diff --git a/postfix/src/global/deliver_request.h b/postfix/src/global/deliver_request.h index a00bcf7a2..c1c5b1dd0 100644 --- a/postfix/src/global/deliver_request.h +++ b/postfix/src/global/deliver_request.h @@ -146,6 +146,11 @@ extern int PRINTFLIKE(4, 5) reject_deliver_request(const char *, /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ #endif diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 512497dab..be7c4541c 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1957,8 +1957,11 @@ extern long var_message_limit; #define VAR_QUEUE_MINFREE "queue_minfree" #define DEF_QUEUE_MINFREE 0 -extern int var_queue_minfree; +extern long var_queue_minfree; + /* + * Light-weight content inspection. + */ #define VAR_HEADER_CHECKS "header_checks" #define DEF_HEADER_CHECKS "" extern char *var_header_checks; diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 9e07af94a..fba54444c 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 "20190922" +#define MAIL_RELEASE_DATE "20191013" #define MAIL_VERSION_NUMBER "3.5" #ifdef SNAPSHOT diff --git a/postfix/src/local/local.c b/postfix/src/local/local.c index 5b478d45a..7cf2d8656 100644 --- a/postfix/src/local/local.c +++ b/postfix/src/local/local.c @@ -875,9 +875,12 @@ static void pre_init(char *unused_name, char **unused_argv) * because that prohibits the delivery agent from updating the queue * file. */ - if (var_mailbox_limit) { - if (var_mailbox_limit < var_message_limit || var_message_limit == 0) - msg_fatal("main.cf configuration error: %s is smaller than %s", + if (ENFORCING_SIZE_LIMIT(var_mailbox_limit)) { + if (!ENFORCING_SIZE_LIMIT(var_message_limit)) + msg_fatal("configuration error: %s is limited but %s is " + "unlimited", VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT); + if (var_mailbox_limit < var_message_limit) + msg_fatal("configuration error: %s is smaller than %s", VAR_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT); set_file_limit(var_mailbox_limit); } diff --git a/postfix/src/postdrop/postdrop.c b/postfix/src/postdrop/postdrop.c index 5e35d1ddd..ca7846431 100644 --- a/postfix/src/postdrop/postdrop.c +++ b/postfix/src/postdrop/postdrop.c @@ -329,7 +329,8 @@ int main(int argc, char **argv) * Stop run-away process accidents by limiting the queue file size. This * is not a defense against DOS attack. */ - if (var_message_limit > 0 && get_file_limit() > var_message_limit) + if (ENFORCING_SIZE_LIMIT(var_message_limit) + && get_file_limit() > var_message_limit) set_file_limit((off_t) var_message_limit); /* diff --git a/postfix/src/postscreen/postscreen_smtpd.c b/postfix/src/postscreen/postscreen_smtpd.c index 78392072f..901a51f88 100644 --- a/postfix/src/postscreen/postscreen_smtpd.c +++ b/postfix/src/postscreen/postscreen_smtpd.c @@ -316,7 +316,7 @@ static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask vstring_sprintf(psc_temp, "250-%s\r\n", var_myhostname); if ((discard_mask & EHLO_MASK_SIZE) == 0) { - if (var_message_limit) + if (ENFORCING_SIZE_LIMIT(var_message_limit)) PSC_EHLO_APPEND1(saved_len, psc_temp, "250-SIZE %lu\r\n", (unsigned long) var_message_limit); else diff --git a/postfix/src/sendmail/sendmail.c b/postfix/src/sendmail/sendmail.c index facdb1d81..575ea4856 100644 --- a/postfix/src/sendmail/sendmail.c +++ b/postfix/src/sendmail/sendmail.c @@ -690,7 +690,8 @@ static void enqueue(const int flags, const char *encoding, * Stop run-away process accidents by limiting the queue file size. This * is not a defense against DOS attack. */ - if (var_message_limit > 0 && get_file_limit() > var_message_limit) + if (ENFORCING_SIZE_LIMIT(var_message_limit) + && get_file_limit() > var_message_limit) set_file_limit((off_t) var_message_limit); /* diff --git a/postfix/src/smtp/smtp_chat.c b/postfix/src/smtp/smtp_chat.c index 9dc15e4cb..bff5986ed 100644 --- a/postfix/src/smtp/smtp_chat.c +++ b/postfix/src/smtp/smtp_chat.c @@ -102,6 +102,11 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ /* System library. */ diff --git a/postfix/src/smtp/smtp_rcpt.c b/postfix/src/smtp/smtp_rcpt.c index 3d00a7cb8..6608ea880 100644 --- a/postfix/src/smtp/smtp_rcpt.c +++ b/postfix/src/smtp/smtp_rcpt.c @@ -106,6 +106,11 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ /* System library. */ diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index afec33d31..a60e60d08 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1258,7 +1258,7 @@ int var_smtpd_rcpt_limit; int var_smtpd_tmout; int var_smtpd_soft_erlim; int var_smtpd_hard_erlim; -int var_queue_minfree; /* XXX use off_t */ +long var_queue_minfree; /* XXX use off_t */ char *var_smtpd_banner; char *var_notify_classes; char *var_client_checks; @@ -1868,7 +1868,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) if ((discard_mask & EHLO_MASK_PIPELINING) == 0) EHLO_APPEND(state, "PIPELINING"); if ((discard_mask & EHLO_MASK_SIZE) == 0) { - if (var_message_limit) + if (ENFORCING_SIZE_LIMIT(var_message_limit)) EHLO_APPEND1(state, "SIZE %lu", (unsigned long) var_message_limit); /* XXX */ else @@ -3510,7 +3510,8 @@ static void receive_data_message(SMTPD_STATE *state, && (proxy == 0 ? (++start, --len) == 0 : len == 1)) break; if (state->err == CLEANUP_STAT_OK) { - if (var_message_limit > 0 && var_message_limit - state->act_size < len + 2) { + if (ENFORCING_SIZE_LIMIT(var_message_limit) + && var_message_limit - state->act_size < len + 2) { state->err = CLEANUP_STAT_SIZE; msg_warn("%s: queue file size limit exceeded", state->queue_id ? state->queue_id : "NOQUEUE"); @@ -3887,7 +3888,7 @@ static int bdat_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) } } /* Block too large chunks. */ - if (var_message_limit > 0 + if (ENFORCING_SIZE_LIMIT(var_message_limit) && state->act_size > var_message_limit - chunk_size) { state->error_mask |= MAIL_ERROR_POLICY; msg_warn("%s: BDAT request from %s exceeds message size limit", @@ -3980,7 +3981,7 @@ static int bdat_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) start = vstring_str(state->bdat_get_buffer); len = VSTRING_LEN(state->bdat_get_buffer); if (state->err == CLEANUP_STAT_OK) { - if (var_message_limit > 0 + if (ENFORCING_SIZE_LIMIT(var_message_limit) && var_message_limit - state->act_size < len + 2) { state->err = CLEANUP_STAT_SIZE; msg_warn("%s: queue file size limit exceeded", @@ -6259,8 +6260,8 @@ static void post_jail_init(char *unused_name, char **unused_argv) * arbitrarily pick a small multiple of the per-message size limit. This * helps to avoid many unneeded (re)transmissions. */ - if (var_queue_minfree > 0 - && var_message_limit > 0 + if (ENFORCING_SIZE_LIMIT(var_queue_minfree) + && ENFORCING_SIZE_LIMIT(var_message_limit) && var_queue_minfree / 1.5 < var_message_limit) msg_warn("%s(%lu) should be at least 1.5*%s(%lu)", VAR_QUEUE_MINFREE, (unsigned long) var_queue_minfree, @@ -6290,7 +6291,6 @@ int main(int argc, char **argv) }; static const CONFIG_INT_TABLE int_table[] = { VAR_SMTPD_RCPT_LIMIT, DEF_SMTPD_RCPT_LIMIT, &var_smtpd_rcpt_limit, 1, 0, - VAR_QUEUE_MINFREE, DEF_QUEUE_MINFREE, &var_queue_minfree, 0, 0, VAR_UNK_CLIENT_CODE, DEF_UNK_CLIENT_CODE, &var_unk_client_code, 0, 0, VAR_BAD_NAME_CODE, DEF_BAD_NAME_CODE, &var_bad_name_code, 0, 0, VAR_UNK_NAME_CODE, DEF_UNK_NAME_CODE, &var_unk_name_code, 0, 0, @@ -6328,6 +6328,10 @@ int main(int argc, char **argv) VAR_SMTPD_POLICY_TRY_LIMIT, DEF_SMTPD_POLICY_TRY_LIMIT, &var_smtpd_policy_try_limit, 1, 0, 0, }; + static const CONFIG_LONG_TABLE long_table[] = { + VAR_QUEUE_MINFREE, DEF_QUEUE_MINFREE, &var_queue_minfree, 0, 0, + 0, + }; static const CONFIG_TIME_TABLE time_table[] = { VAR_SMTPD_TMOUT, DEF_SMTPD_TMOUT, &var_smtpd_tmout, 1, 0, VAR_SMTPD_ERR_SLEEP, DEF_SMTPD_ERR_SLEEP, &var_smtpd_err_sleep, 0, 0, @@ -6504,6 +6508,7 @@ int main(int argc, char **argv) single_server_main(argc, argv, smtpd_service, CA_MAIL_SERVER_NINT_TABLE(nint_table), CA_MAIL_SERVER_INT_TABLE(int_table), + CA_MAIL_SERVER_LONG_TABLE(long_table), CA_MAIL_SERVER_STR_TABLE(str_table), CA_MAIL_SERVER_RAW_TABLE(raw_table), CA_MAIL_SERVER_BOOL_TABLE(bool_table), diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index 90860065e..a8c7bff99 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -5380,7 +5380,7 @@ char *smtpd_check_size(SMTPD_STATE *state, off_t size) /* * Check against file size limit. */ - if (var_message_limit > 0 && size > var_message_limit) { + if (ENFORCING_SIZE_LIMIT(var_message_limit) && size > var_message_limit) { (void) smtpd_check_reject(state, MAIL_ERROR_POLICY, 552, "5.3.4", "Message size exceeds fixed limit"); diff --git a/postfix/src/tls/tls_certkey.c b/postfix/src/tls/tls_certkey.c index 74b2fd1cd..abc92454f 100644 --- a/postfix/src/tls/tls_certkey.c +++ b/postfix/src/tls/tls_certkey.c @@ -74,6 +74,11 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ /* System library. */ diff --git a/postfix/src/util/nbbio.c b/postfix/src/util/nbbio.c index d8ddfc6f2..e9ccc3878 100644 --- a/postfix/src/util/nbbio.c +++ b/postfix/src/util/nbbio.c @@ -133,6 +133,11 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ /* diff --git a/postfix/src/util/netstring.c b/postfix/src/util/netstring.c index fae8757dc..0edd80e1b 100644 --- a/postfix/src/util/netstring.c +++ b/postfix/src/util/netstring.c @@ -263,7 +263,7 @@ VSTRING *netstring_get(VSTREAM *stream, VSTRING *buf, ssize_t limit) ssize_t len; len = netstring_get_length(stream); - if (limit && len > limit) + if (ENFORCING_SIZE_LIMIT(limit) && len > limit) netstring_except(stream, NETSTRING_ERR_SIZE); netstring_get_data(stream, buf, len); return (buf); diff --git a/postfix/src/util/sys_defs.h b/postfix/src/util/sys_defs.h index 6e998cb35..17e52b229 100644 --- a/postfix/src/util/sys_defs.h +++ b/postfix/src/util/sys_defs.h @@ -1681,8 +1681,8 @@ typedef int pid_t; * Bit banging!! There is no official constant that defines the INT_MAX * equivalent for off_t, ssize_t, etc. Wietse came up with the following * macro that works as long as off_t, ssize_t, etc. use one's or two's - * complement logic (that is, the maximum value is binary 01...1). Don't - * use right-shift for signed types: the result is implementation-defined. + * complement logic (that is, the maximum value is binary 01...1). Don't use + * right-shift for signed types: the result is implementation-defined. */ #include #define __MAXINT__(T) ((T) ~(((T) 1) << ((sizeof(T) * CHAR_BIT) - 1))) @@ -1694,6 +1694,11 @@ typedef int pid_t; #define SSIZE_T_MAX __MAXINT__(ssize_t) #endif + /* + * Consistent enforcement of size limits. + */ +#define ENFORCING_SIZE_LIMIT(param) ((param) > 0) + /* * Setting globals like h_errno can be problematic when Postfix is linked * with multi-threaded libraries. diff --git a/postfix/src/util/vstream_tweak.c b/postfix/src/util/vstream_tweak.c index a2e220c45..75d2e7469 100644 --- a/postfix/src/util/vstream_tweak.c +++ b/postfix/src/util/vstream_tweak.c @@ -32,6 +32,11 @@ /* IBM T.J. Watson Research /* P.O. Box 704 /* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA /*--*/ /* System library. */ diff --git a/postfix/src/virtual/virtual.c b/postfix/src/virtual/virtual.c index 29b1b7135..41f94e98f 100644 --- a/postfix/src/virtual/virtual.c +++ b/postfix/src/virtual/virtual.c @@ -503,9 +503,12 @@ static void pre_init(char *unused_name, char **unused_argv) * because that prohibits the delivery agent from updating the queue * file. */ - if (var_virt_mailbox_limit) { - if (var_virt_mailbox_limit < var_message_limit || var_message_limit == 0) - msg_fatal("main.cf configuration error: %s is smaller than %s", + if (ENFORCING_SIZE_LIMIT(var_virt_mailbox_limit)) { + if (!ENFORCING_SIZE_LIMIT(var_message_limit)) + msg_fatal("configuration error: %s is limited but %s is " + "unlimited", VAR_VIRT_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT); + if (var_virt_mailbox_limit < var_message_limit) + msg_fatal("configuration error: %s is smaller than %s", VAR_VIRT_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT); set_file_limit(var_virt_mailbox_limit); }