From: Wietse Z Venema Date: Fri, 9 Feb 2024 05:00:00 +0000 (-0500) Subject: postfix-3.9-20240209 X-Git-Tag: v3.9.0~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=403f8ce4a1bc9f4718ccb98000a5e9d50749108a;p=thirdparty%2Fpostfix.git postfix-3.9-20240209 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index fc0fa24c6..4ce9adf71 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -27826,3 +27826,23 @@ Apologies for any names omitted. global/dict_mongodb.c, global/dict_mongodb.h, global/mail_dict.c, global/Makefile.in, postconf/Makefile.in, proto/INSTALL.html, postfix/postfix.c. + +20240209 + + Safety: enforce a sane but generous upper bound (100) for + the number of DNS resource records that the Postfix DNS + client library will admit into a list. This is 20x the + default smtp_mx_address_limit value for the number of DNS + records that the Postfix SMTP client is willing to consider. + Log a warning "dropping records after qname=X qtype=Y" when + a list cannot accept more elements. This prevents a tail + recursion crash that degrades mail delivery performance. + Problem report by Toshifumi Sakaguchi. Files: dns/dns_rr.[hc], + global/mail_params.h. + + Performance: eliminate worst-case behavior where the queue + manager defers delivery to all destinations over a specific + delivery transport, after only a single delivery agent + failure. The scheduler now throttles one destination, and + allows deliveries to other destinations to keep making + progress. Files: *qmgr/qmgr_deliver.c. diff --git a/postfix/html/MONGODB_README.html b/postfix/html/MONGODB_README.html index 278c0c813..7835bab78 100644 --- a/postfix/html/MONGODB_README.html +++ b/postfix/html/MONGODB_README.html @@ -79,7 +79,7 @@ table lookup in main.cf, for example:

The file /etc/postfix/mongo-aliases.cf can specify a number of -parameters. For a complete description, see the mongodb_table(5) +parameters. For a complete description, see the mongodb_table(5) manual page.

Example: virtual(5) alias maps

diff --git a/postfix/proto/stop.spell-cc b/postfix/proto/stop.spell-cc index 41d79beed..db5c3564c 100644 --- a/postfix/proto/stop.spell-cc +++ b/postfix/proto/stop.spell-cc @@ -1834,3 +1834,4 @@ mongodbconf Dextrous Mongo SUD +qtype diff --git a/postfix/proto/stop.spell-history b/postfix/proto/stop.spell-history index d5e53d3a8..1a0712a0f 100644 --- a/postfix/proto/stop.spell-history +++ b/postfix/proto/stop.spell-history @@ -73,3 +73,5 @@ Philosof MONGODB Refactored Vijay +Sakaguchi +Toshifumi diff --git a/postfix/src/dns/Makefile.in b/postfix/src/dns/Makefile.in index 3ebf75f81..769354508 100644 --- a/postfix/src/dns/Makefile.in +++ b/postfix/src/dns/Makefile.in @@ -286,6 +286,7 @@ dns_lookup.o: ../../include/vstring.h dns_lookup.o: dns.h dns_lookup.o: dns_lookup.c dns_rr.o: ../../include/check_arg.h +dns_rr.o: ../../include/mail_params.h dns_rr.o: ../../include/msg.h dns_rr.o: ../../include/myaddrinfo.h dns_rr.o: ../../include/mymalloc.h diff --git a/postfix/src/dns/dns_rr.c b/postfix/src/dns/dns_rr.c index 3fde10e58..deba784b7 100644 --- a/postfix/src/dns/dns_rr.c +++ b/postfix/src/dns/dns_rr.c @@ -54,6 +54,8 @@ /* /* DNS_RR *dns_srv_rr_sort(list) /* DNS_RR *list; +/* +/* int var_dns_rr_list_limit; /* AUXILIARY FUNCTIONS /* DNS_RR *dns_rr_create_nopref(qname, rname, type, class, ttl, /* data, data_len) @@ -98,6 +100,9 @@ /* dns_rr_append() appends a resource record to a (list of) resource /* record(s). /* A null input list is explicitly allowed. +/* This function will log a warning and will discard the +/* resource record, when a list already contains var_dns_rr_list_limit +/* elements (default: 100). /* /* dns_rr_sort() sorts a list of resource records into ascending /* order according to a user-specified criterion. The result is the @@ -146,10 +151,19 @@ #include #include +/* Global library. */ + +#include + /* DNS library. */ #include "dns.h" + /* + * Global, to make code testable. + */ +int var_dns_rr_list_limit = DEF_DNS_RR_LIST_LIMIT; + /* dns_rr_create - fill in resource record structure */ DNS_RR *dns_rr_create(const char *qname, const char *rname, @@ -218,18 +232,40 @@ DNS_RR *dns_rr_copy(DNS_RR *src) return (dst); } -/* dns_rr_append - append resource record to list */ +/* dns_rr_append_with_limit - append resource record to limited list */ -DNS_RR *dns_rr_append(DNS_RR *list, DNS_RR *rr) +static DNS_RR *dns_rr_append_with_limit(DNS_RR *list, DNS_RR *rr, int limit) { + + /* + * To avoid log spam, remember a limited amount of information about a + * past warning. When anomalies happen frequently, then it is OK that + * some anomaly will not be logged, as long as the limit is enforced. + */ if (list == 0) { list = rr; + } else if (limit > 1) { + list->next = dns_rr_append_with_limit(list->next, rr, limit - 1); } else { - list->next = dns_rr_append(list->next, rr); + static DNS_RR *logged_node; + + if (logged_node != list) { + logged_node = list; + msg_warn("dns_rr_append: dropping records after qname=%s qtype=%s", + list->qname, dns_strtype(list->type)); + } + dns_rr_free(rr); } return (list); } +/* dns_rr_append - append resource record to list */ + +DNS_RR *dns_rr_append(DNS_RR *list, DNS_RR *rr) +{ + return (dns_rr_append_with_limit(list, rr, var_dns_rr_list_limit)); +} + /* dns_rr_compare_pref_ipv6 - compare records by preference, ipv6 preferred */ int dns_rr_compare_pref_ipv6(DNS_RR *a, DNS_RR *b) diff --git a/postfix/src/dns/test_dns_lookup.c b/postfix/src/dns/test_dns_lookup.c index e25f52337..9c0692b0d 100644 --- a/postfix/src/dns/test_dns_lookup.c +++ b/postfix/src/dns/test_dns_lookup.c @@ -80,7 +80,7 @@ int main(int argc, char **argv) var_dnssec_probe = ""; msg_vstream_init(argv[0], VSTREAM_ERR); - while ((ch = GETOPT(argc, argv, "f:npvs")) > 0) { + while ((ch = GETOPT(argc, argv, "f:l:npvs")) > 0) { switch (ch) { case 'v': msg_verbose++; @@ -88,6 +88,9 @@ int main(int argc, char **argv) case 'f': dns_rr_filter_compile("DNS reply filter", optarg); break; + case 'l': + var_dns_rr_list_limit = atoi(optarg); + break; case 'n': lflags |= DNS_REQ_FLAG_NCACHE_TTL; break; diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 1f03b0b34..fea312ad0 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -4384,6 +4384,16 @@ extern int var_idna2003_compat; #define DEF_DNS_NCACHE_TTL_FIX 0 extern bool var_dns_ncache_ttl_fix; + /* + * A generous safety limit for the number of DNS resource records that the + * Postfix DNS client library will admit into a list. The default is 20x the + * default limit on the number address records that the Postfix SMTP client + * is willing to consider. + */ +#define VAR_DNS_RR_LIST_LIMIT "dns_resource_list_limit" +#define DEF_DNS_RR_LIST_LIMIT 100 +extern int var_dns_rr_list_limit; + /* * Logging. As systems evolve over time, logging becomes more challenging. */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 34b806ed0..79dcedebf 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 "20240208" +#define MAIL_RELEASE_DATE "20240209" #define MAIL_VERSION_NUMBER "3.9" #ifdef SNAPSHOT diff --git a/postfix/src/oqmgr/qmgr_deliver.c b/postfix/src/oqmgr/qmgr_deliver.c index 9be6963aa..6c093506b 100644 --- a/postfix/src/oqmgr/qmgr_deliver.c +++ b/postfix/src/oqmgr/qmgr_deliver.c @@ -283,6 +283,7 @@ static void qmgr_deliver_update(int unused_event, void *context) * The queue itself won't go away before we dispose of the current queue * entry. */ +#if 0 if (status == DELIVER_STAT_CRASH) { message->flags |= DELIVER_STAT_DEFER; #if 0 @@ -317,6 +318,7 @@ static void qmgr_deliver_update(int unused_event, void *context) qmgr_defer_transport(transport, &dsb->dsn); return; } +#endif /* * This message must be tried again. @@ -331,7 +333,9 @@ static void qmgr_deliver_update(int unused_event, void *context) */ #define SUSPENDED "delivery temporarily suspended: " - if (status == DELIVER_STAT_DEFER) { + if (status == DELIVER_STAT_CRASH) + (void) DSN_SIMPLE(&dsb->dsn, "4.3.0", "unknown mail transport error"); + if (status == DELIVER_STAT_CRASH || status == DELIVER_STAT_DEFER) { message->flags |= DELIVER_STAT_DEFER; if (VSTRING_LEN(dsb->status)) { /* Sanitize the DSN status/reason from the delivery agent. */ diff --git a/postfix/src/qmgr/qmgr_deliver.c b/postfix/src/qmgr/qmgr_deliver.c index 441aed1f9..6c880ce74 100644 --- a/postfix/src/qmgr/qmgr_deliver.c +++ b/postfix/src/qmgr/qmgr_deliver.c @@ -288,6 +288,7 @@ static void qmgr_deliver_update(int unused_event, void *context) * The queue itself won't go away before we dispose of the current queue * entry. */ +#if 0 if (status == DELIVER_STAT_CRASH) { message->flags |= DELIVER_STAT_DEFER; #if 0 @@ -322,6 +323,7 @@ static void qmgr_deliver_update(int unused_event, void *context) qmgr_defer_transport(transport, &dsb->dsn); return; } +#endif /* * This message must be tried again. @@ -336,7 +338,9 @@ static void qmgr_deliver_update(int unused_event, void *context) */ #define SUSPENDED "delivery temporarily suspended: " - if (status == DELIVER_STAT_DEFER) { + if (status == DELIVER_STAT_CRASH) + (void) DSN_SIMPLE(&dsb->dsn, "4.3.0", "unknown mail transport error"); + if (status == DELIVER_STAT_CRASH || status == DELIVER_STAT_DEFER) { message->flags |= DELIVER_STAT_DEFER; if (VSTRING_LEN(dsb->status)) { /* Sanitize the DSN status/reason from the delivery agent. */