diff options
| author | rpaulo <rpaulo@NetBSD.org> | 2006-12-21 02:27:16 +0000 |
|---|---|---|
| committer | rpaulo <rpaulo@NetBSD.org> | 2006-12-21 02:27:16 +0000 |
| commit | 0225a7dd90a5c990ec79a8f3260e377c5fddfbe3 (patch) | |
| tree | de7487176ba6a3b847134afd4f6990ce6123b46f /gnu | |
| parent | 610c0515b70335201b523e2787be27816bf7de3b (diff) | |
postfix-2.3.5
Diffstat (limited to 'gnu')
28 files changed, 402 insertions, 98 deletions
diff --git a/gnu/dist/postfix/AAAREADME b/gnu/dist/postfix/AAAREADME index d68a0f16d18..e78b4d8e17f 100644 --- a/gnu/dist/postfix/AAAREADME +++ b/gnu/dist/postfix/AAAREADME @@ -135,7 +135,6 @@ Postfix daemons: src/cleanup/ Canonicalize and enqueue mail src/discard/ Trivial discard mailer src/error/ Trivial error mailer - src/lmtp/ LMTP client src/local/ Local delivery src/master/ Postfix resident superserver src/oqmgr/ Old queue manager @@ -144,9 +143,10 @@ Postfix daemons: src/qmgr/ Queue manager src/qmqpd/ QMQPD server src/showq/ List Postfix queue status - src/smtp/ SMTP client + src/smtp/ SMTP and LMTP client src/smtpd/ SMTP server src/spawn/ Run non-Postfix server + src/tlsmgr/ TLS session keys and random pool src/trivial-rewrite/ Address rewriting and resolving src/verify/ address verification service src/virtual/ virtual mailbox-only delivery agent diff --git a/gnu/dist/postfix/HISTORY b/gnu/dist/postfix/HISTORY index b2660369271..3f2ecad6d8e 100644 --- a/gnu/dist/postfix/HISTORY +++ b/gnu/dist/postfix/HISTORY @@ -12769,3 +12769,96 @@ Apologies for any names omitted. Bugfix: null pointer bug when receiving a non-protocol response on a cached SMTP/LMTP connection. Report by Brian Kantor. Fix by Victor Duchovni. File: smtp/smtp_reuse.c. + +20061113 + + Bugfix: the Postfix install/upgrade procedure broke with + non-default config_directory. File: conf/post-install. + +20061115 + + Bugfix: null pointer bug in end-of-header Milter action + when the last header line is too large. Reported by Mark + Martinec. The root of the problem is that the MIME state + engine may execute up to three call-back functions when it + reaches the end of the headers, before it returns to the + caller; as long as call-backs return no result, each call-back + has to check for itself if a previous call-back ran into a + problem. File: milter/milter8.c. + + Workaround: reduce effective header_size_limit to 60000 + when Milter inspection is enabled, to avoid breaking the + Milter protocol request length limit. File: + cleanup/cleanup_message.c. + +20061123 + + Workaround: more agressive early refill of in-memory + recipients to prevent a worst-case scenario where the queue + manager became starved until after the last batch of slow + in-memory recipients of jumbo multi-recipient mail. Files: + qmgr/qmgr_job.c. + + Safety: don't read more than 5000 recipients at a time, to + avoid spending too much time away from interrupts. File: + qmgr/qmgr_message.c. + +20061201 + + Workaround: don't complain with "Error 0" in the trivial-rewrite, + verify, proxymap or connection cache client when the server + exits after the client sends its request. We still complain, + however, when the problem persists. Files: global/rewrite_clnt.c, + global/resolve_clnt.c, global/verify_clnt.c, global/scache_clnt.c, + global/dict_proxy.c. + + + Safety: the header_size_limit is now enforced more strictly, + to avoid inter-operability problems with the Milter protocol. + Long headers are truncated at a line boundary if possible, + otherwise they are cut between line boundaries. File: + cleanup/cleanup_out.c. + +20061203 + + Bugfix (introduced with Postfix 2.2): with SMTP server + tarpit delays of smtp_rset_timeout or larger, the SMTP + client could get out of sync with the server while reusing + a connection. The symptoms were "recipient rejected .. in + reply to DATA". Fix by Victor Duchovni and Wietse. File: + smtp/smtp_proto.c. + +20061207 + + Compatibility with Postfix < 2.3: undo the change to bounce + instead of defer after pipe-to-command delivery fails with + a signal. File: global/pipe_command.c. + +20061208 + + Workaround: apparently, some mail software removes or hides + "<postmaster>" in the Postfix bounce text, because it + processes the text as if it were HTML. This confuses users. + The bounce template has been updated to remove the < and + >. File: bounce/bounce_templates.c. + + Cleanup: when smtp_generic_maps is turned on, don't parse + MIME structures in the message body. Victor Duchovni. File: + smtp/smtp_proto.c. + +20061210 + + Robustness: low-cost re-entrancy guard that allows daemons + to call msg_fatal() etc. from a signal handler, without + risking memory corruption, or deadlock on Redhat Linux. + This works provided that the signal handler never returns. + In that special case we need not guarantee after-the-fact + consistency of the interrupted process. File: util/msg_output.c. + + Robustness: replace exit() calls by _exit(). File: util/msg.c, + bounce/bounce_cleanup.c. + + Cleanup: document under what conditions these protections + work, with REENTRANCY sections in the relevant man pages. + Files: util/vbuf.c. util/msg.c, util/msg_output.c. + diff --git a/gnu/dist/postfix/README_FILES/ADDRESS_REWRITING_README b/gnu/dist/postfix/README_FILES/ADDRESS_REWRITING_README index 5a701344a87..b7e75ad5acd 100644 --- a/gnu/dist/postfix/README_FILES/ADDRESS_REWRITING_README +++ b/gnu/dist/postfix/README_FILES/ADDRESS_REWRITING_README @@ -787,14 +787,14 @@ mailbox, or delivery to non-Postfix command. Content-Description: Notification Content-Type: text/plain - This is the Postfix program at host spike.porcupine.org. + This is the mail system at host spike.porcupine.org. Enclosed is the mail delivery report that you requested. - The Postfix program + The mail system <postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 - Ok + 2.1.5 Ok The second part of the report is in machine-readable form, and includes the following information: @@ -814,13 +814,13 @@ version 2.3 and later. Reporting-MTA: dns; spike.porcupine.org X-Postfix-Queue-ID: 84863BC0E5 X-Postfix-Sender: rfc822; wietse@porcupine.org - Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) + Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) Final-Recipient: rfc822; postfix-users@postfix.org Action: deliverable - Status: 2.0.0 + Status: 2.1.5 Remote-MTA: dns; mail.cloud9.net - Diagnostic-Code: smtp; 250 Ok + Diagnostic-Code: smtp; 250 2.1.5 Ok The third part of the report contains the message that Postfix would have delivered, including From: and To: message headers, so that you can see any @@ -831,10 +831,10 @@ no body content so none is shown in the example below. Content-Type: message/rfc822 Received: by spike.porcupine.org (Postfix, from userid 1001) - id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT) + id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST) Subject: probe To: postfix-users@postfix.org - Message-Id: <20040413232743.84863BC0E5@spike.porcupine.org> - Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) + Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org> + Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) From: wietse@porcupine.org (Wietse Venema) diff --git a/gnu/dist/postfix/html/ADDRESS_REWRITING_README.html b/gnu/dist/postfix/html/ADDRESS_REWRITING_README.html index 4c1c53813ec..f2243516d26 100644 --- a/gnu/dist/postfix/html/ADDRESS_REWRITING_README.html +++ b/gnu/dist/postfix/html/ADDRESS_REWRITING_README.html @@ -1174,13 +1174,13 @@ to mailbox, or delivery to non-Postfix command. </p> Content-Description: Notification Content-Type: text/plain -This is the Postfix program at host spike.porcupine.org. +This is the mail system at host spike.porcupine.org. Enclosed is the mail delivery report that you requested. - The Postfix program + The mail system -<postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 Ok +<postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok </pre> </blockquote> @@ -1210,13 +1210,13 @@ Content-Type: message/delivery-status Reporting-MTA: dns; spike.porcupine.org X-Postfix-Queue-ID: 84863BC0E5 X-Postfix-Sender: rfc822; wietse@porcupine.org -Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) +Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) Final-Recipient: rfc822; postfix-users@postfix.org Action: deliverable -Status: 2.0.0 +Status: 2.1.5 Remote-MTA: dns; mail.cloud9.net -Diagnostic-Code: smtp; 250 Ok +Diagnostic-Code: smtp; 250 2.1.5 Ok </pre> </blockquote> @@ -1232,11 +1232,11 @@ Content-Description: Message Content-Type: message/rfc822 Received: by spike.porcupine.org (Postfix, from userid 1001) - id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT) + id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST) Subject: probe To: postfix-users@postfix.org -Message-Id: <20040413232743.84863BC0E5@spike.porcupine.org> -Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) +Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org> +Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) From: wietse@porcupine.org (Wietse Venema) </pre> </blockquote> diff --git a/gnu/dist/postfix/html/bounce.5.html b/gnu/dist/postfix/html/bounce.5.html index 7d5ebac31f2..e6c23320c51 100644 --- a/gnu/dist/postfix/html/bounce.5.html +++ b/gnu/dist/postfix/html/bounce.5.html @@ -81,7 +81,7 @@ BOUNCE(5) BOUNCE(5) I'm sorry to have to inform you that your message could not be delivered to one or more recipients. It's attached below. - For further assistance, please send mail to <postmaster> + For further assistance, please send mail to postmaster. If you do so, please include this problem report. You can delete your own text from the attached returned message. diff --git a/gnu/dist/postfix/man/man5/bounce.5 b/gnu/dist/postfix/man/man5/bounce.5 index e293be1b4d4..ec74183cf42 100644 --- a/gnu/dist/postfix/man/man5/bounce.5 +++ b/gnu/dist/postfix/man/man5/bounce.5 @@ -1,4 +1,4 @@ -.\" $NetBSD: bounce.5,v 1.1.1.2 2006/08/27 00:38:02 rpaulo Exp $ +.\" $NetBSD: bounce.5,v 1.1.1.3 2006/12/21 02:29:28 rpaulo Exp $ .\" .TH BOUNCE 5 .ad @@ -93,7 +93,7 @@ This is the mail system at host $myhostname. I'm sorry to have to inform you that your message could not be delivered to one or more recipients. It's attached below. -For further assistance, please send mail to <postmaster> +For further assistance, please send mail to postmaster. If you do so, please include this problem report. You can delete your own text from the attached returned message. diff --git a/gnu/dist/postfix/proto/ADDRESS_REWRITING_README.html b/gnu/dist/postfix/proto/ADDRESS_REWRITING_README.html index 76c78e0cb49..3fef9064348 100644 --- a/gnu/dist/postfix/proto/ADDRESS_REWRITING_README.html +++ b/gnu/dist/postfix/proto/ADDRESS_REWRITING_README.html @@ -1174,13 +1174,13 @@ to mailbox, or delivery to non-Postfix command. </p> Content-Description: Notification Content-Type: text/plain -This is the Postfix program at host spike.porcupine.org. +This is the mail system at host spike.porcupine.org. Enclosed is the mail delivery report that you requested. - The Postfix program + The mail system -<postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 Ok +<postfix-users@postfix.org>: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok </pre> </blockquote> @@ -1210,13 +1210,13 @@ Content-Type: message/delivery-status Reporting-MTA: dns; spike.porcupine.org X-Postfix-Queue-ID: 84863BC0E5 X-Postfix-Sender: rfc822; wietse@porcupine.org -Arrival-Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) +Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) Final-Recipient: rfc822; postfix-users@postfix.org Action: deliverable -Status: 2.0.0 +Status: 2.1.5 Remote-MTA: dns; mail.cloud9.net -Diagnostic-Code: smtp; 250 Ok +Diagnostic-Code: smtp; 250 2.1.5 Ok </pre> </blockquote> @@ -1232,11 +1232,11 @@ Content-Description: Message Content-Type: message/rfc822 Received: by spike.porcupine.org (Postfix, from userid 1001) - id 84863BC0E5; Tue, 13 Apr 2004 19:27:43 -0400 (EDT) + id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST) Subject: probe To: postfix-users@postfix.org -Message-Id: <20040413232743.84863BC0E5@spike.porcupine.org> -Date: Tue, 13 Apr 2004 19:27:43 -0400 (EDT) +Message-Id: <20061126220101.84863BC0E5@spike.porcupine.org> +Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST) From: wietse@porcupine.org (Wietse Venema) </pre> </blockquote> diff --git a/gnu/dist/postfix/proto/bounce b/gnu/dist/postfix/proto/bounce index f770a5e33e5..842cad9b8df 100644 --- a/gnu/dist/postfix/proto/bounce +++ b/gnu/dist/postfix/proto/bounce @@ -81,7 +81,7 @@ # I'm sorry to have to inform you that your message could not # be delivered to one or more recipients. It's attached below. # -# For further assistance, please send mail to <postmaster> +# For further assistance, please send mail to postmaster. # # If you do so, please include this problem report. You can # delete your own text from the attached returned message. diff --git a/gnu/dist/postfix/src/bounce/bounce_cleanup.c b/gnu/dist/postfix/src/bounce/bounce_cleanup.c index ccda852c5d6..bc6d01a340e 100644 --- a/gnu/dist/postfix/src/bounce/bounce_cleanup.c +++ b/gnu/dist/postfix/src/bounce/bounce_cleanup.c @@ -1,4 +1,4 @@ -/* $NetBSD: bounce_cleanup.c,v 1.1.1.3 2006/07/19 01:17:17 rpaulo Exp $ */ +/* $NetBSD: bounce_cleanup.c,v 1.1.1.4 2006/12/21 02:31:23 rpaulo Exp $ */ /*++ /* NAME @@ -131,7 +131,7 @@ static void bounce_cleanup_sig(int sig) */ if (bounce_cleanup_path) (void) unlink(vstring_str(bounce_cleanup_path)); - exit(sig); + _exit(sig); } /* bounce_cleanup_register - register logfile to clean up */ diff --git a/gnu/dist/postfix/src/bounce/bounce_templates.c b/gnu/dist/postfix/src/bounce/bounce_templates.c index 0f2be3da172..23ccc60deb9 100644 --- a/gnu/dist/postfix/src/bounce/bounce_templates.c +++ b/gnu/dist/postfix/src/bounce/bounce_templates.c @@ -1,4 +1,4 @@ -/* $NetBSD: bounce_templates.c,v 1.1.1.2 2006/08/27 00:39:27 rpaulo Exp $ */ +/* $NetBSD: bounce_templates.c,v 1.1.1.3 2006/12/21 02:31:26 rpaulo Exp $ */ /*++ /* NAME @@ -100,7 +100,7 @@ static const char *def_bounce_failure_body[] = { "I'm sorry to have to inform you that your message could not", "be delivered to one or more recipients. It's attached below.", "", - "For further assistance, please send mail to <" MAIL_ADDR_POSTMASTER ">", + "For further assistance, please send mail to " MAIL_ADDR_POSTMASTER ".", "", "If you do so, please include this problem report. You can", "delete your own text from the attached returned message.", @@ -136,7 +136,7 @@ static const char *def_bounce_delay_body[] = { , "It will be retried until it is $maximal_queue_lifetime_days day(s) old.", "", - "For further assistance, please send mail to <" MAIL_ADDR_POSTMASTER ">", + "For further assistance, please send mail to " MAIL_ADDR_POSTMASTER ".", "", "If you do so, please include this problem report. You can", "delete your own text from the attached returned message.", diff --git a/gnu/dist/postfix/src/cleanup/cleanup_message.c b/gnu/dist/postfix/src/cleanup/cleanup_message.c index 6c11466629f..138d578dd87 100644 --- a/gnu/dist/postfix/src/cleanup/cleanup_message.c +++ b/gnu/dist/postfix/src/cleanup/cleanup_message.c @@ -1,4 +1,4 @@ -/* $NetBSD: cleanup_message.c,v 1.1.1.12 2006/08/27 00:39:32 rpaulo Exp $ */ +/* $NetBSD: cleanup_message.c,v 1.1.1.13 2006/12/21 02:31:34 rpaulo Exp $ */ /*++ /* NAME @@ -599,6 +599,16 @@ static void cleanup_header_done_callback(void *context) time_t tv; /* + * XXX Workaround: when we reach the end of headers, mime_state_update() + * may execute up to three call-backs before returning to the caller: + * head_out(), head_end(), and body_out() or body_end(). As long as + * call-backs don't return a result, each call-back has to check for + * itself if the previous call-back experienced a problem. + */ + if (CLEANUP_OUT_OK(state) == 0) + return; + + /* * Add a missing (Resent-)Message-Id: header. The message ID gives the * time in GMT units, plus the local queue ID. * @@ -709,6 +719,16 @@ static void cleanup_body_callback(void *context, int type, CLEANUP_STATE *state = (CLEANUP_STATE *) context; /* + * XXX Workaround: when we reach the end of headers, mime_state_update() + * may execute up to three call-backs before returning to the caller: + * head_out(), head_end(), and body_out() or body_end(). As long as + * call-backs don't return a result, each call-back has to check for + * itself if the previous call-back experienced a problem. + */ + if (CLEANUP_OUT_OK(state) == 0) + return; + + /* * Crude message body content filter for emergencies. This code has * several problems: it sees one line at a time; it looks at long lines * only in chunks of line_length_limit (2048) characters; it is easily @@ -895,6 +915,15 @@ void cleanup_message(CLEANUP_STATE *state, int type, const char *buf, ssize_t (void *) state); /* + * XXX Workaround: truncate a long message header so that we don't exceed + * the Milter request size limit of 65535. + */ +#define KLUDGE_HEADER_LIMIT 60000 + if ((cleanup_milters || state->milters) + && var_header_limit > KLUDGE_HEADER_LIMIT) + var_header_limit = KLUDGE_HEADER_LIMIT; + + /* * Pass control to the header processing routine. */ state->action = cleanup_message_headerbody; diff --git a/gnu/dist/postfix/src/cleanup/cleanup_milter.c b/gnu/dist/postfix/src/cleanup/cleanup_milter.c index 88a0e9fb921..eb4fa0c1ad2 100644 --- a/gnu/dist/postfix/src/cleanup/cleanup_milter.c +++ b/gnu/dist/postfix/src/cleanup/cleanup_milter.c @@ -1,4 +1,4 @@ -/* $NetBSD: cleanup_milter.c,v 1.1.1.4 2006/11/07 02:57:14 rpaulo Exp $ */ +/* $NetBSD: cleanup_milter.c,v 1.1.1.5 2006/12/21 02:31:36 rpaulo Exp $ */ /*++ /* NAME @@ -1699,6 +1699,8 @@ static void usage(void) msg_warn(" del_rcpt addr"); } +/* flatten_args - unparse partial command line */ + static void flatten_args(VSTRING *buf, char **argv) { char **cpp; @@ -1712,6 +1714,8 @@ static void flatten_args(VSTRING *buf, char **argv) VSTRING_TERMINATE(buf); } +/* open_queue_file - open an unedited queue file (all-zero dummy PTRs) */ + static void open_queue_file(CLEANUP_STATE *state, const char *path) { VSTRING *buf = vstring_alloc(100); @@ -1722,6 +1726,13 @@ static void open_queue_file(CLEANUP_STATE *state, const char *path) long rcpt_count; long qmgr_opts; + if (state->dst != 0) { + msg_warn("closing %s", cleanup_path); + vstream_fclose(state->dst); + state->dst = 0; + myfree(cleanup_path); + cleanup_path = 0; + } if ((state->dst = vstream_fopen(path, O_RDWR, 0)) == 0) { msg_warn("open %s: %m", path); } else { @@ -1796,6 +1807,7 @@ int main(int unused_argc, char **argv) msg_vstream_init(argv[0], VSTREAM_ERR); var_line_limit = DEF_LINE_LIMIT; + var_header_limit = DEF_HEADER_LIMIT; for (;;) { ARGV *argv; diff --git a/gnu/dist/postfix/src/cleanup/cleanup_out.c b/gnu/dist/postfix/src/cleanup/cleanup_out.c index bcbc4c9e636..bffe820737b 100644 --- a/gnu/dist/postfix/src/cleanup/cleanup_out.c +++ b/gnu/dist/postfix/src/cleanup/cleanup_out.c @@ -1,4 +1,4 @@ -/* $NetBSD: cleanup_out.c,v 1.1.1.5 2006/07/19 01:17:20 rpaulo Exp $ */ +/* $NetBSD: cleanup_out.c,v 1.1.1.6 2006/12/21 02:31:37 rpaulo Exp $ */ /*++ /* NAME @@ -177,9 +177,22 @@ void cleanup_out_header(CLEANUP_STATE *state, VSTRING *header_buf) * of such header lines. NB: This code destroys the header. We could try * to avoid clobbering it, but we're not going to use the data any * further. + * + * XXX We prefer to truncate a header at the last line boundary before the + * header size limit. If this would undershoot the limit by more than + * 10%, we truncate between line boundaries to avoid losing too much + * text. This "unkind cut" may result in syntax errors and may trigger + * warnings from down-stream MTAs. */ for (line = start; line; line = next_line) { next_line = split_at(line, '\n'); + if ((next_line ? next_line - 1 : line + strlen(line)) + > start + var_header_limit) { + if (line - start > 0.9 * var_header_limit) /* nice cut */ + break; + start[var_header_limit] = 0; /* unkind cut */ + next_line = 0; + } if (line == start || IS_SPACE_TAB(*line)) { cleanup_out_string(state, REC_TYPE_NORM, line); } else { diff --git a/gnu/dist/postfix/src/global/dict_proxy.c b/gnu/dist/postfix/src/global/dict_proxy.c index 984e3ad7b5e..27c9bcca5ea 100644 --- a/gnu/dist/postfix/src/global/dict_proxy.c +++ b/gnu/dist/postfix/src/global/dict_proxy.c @@ -1,4 +1,4 @@ -/* $NetBSD: dict_proxy.c,v 1.1.1.5 2006/07/19 01:17:23 rpaulo Exp $ */ +/* $NetBSD: dict_proxy.c,v 1.1.1.6 2006/12/21 02:31:53 rpaulo Exp $ */ /*++ /* NAME @@ -92,6 +92,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key) DICT_PROXY *dict_proxy = (DICT_PROXY *) dict; VSTREAM *stream; int status; + int count = 0; /* * The client and server live in separate processes that may start and @@ -105,6 +106,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key) for (;;) { stream = clnt_stream_access(proxy_stream); errno = 0; + count += 1; if (attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_LOOKUP, ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict->name, @@ -116,7 +118,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key) ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status, ATTR_TYPE_STR, MAIL_ATTR_VALUE, dict_proxy->result, ATTR_TYPE_END) != 2) { - if (msg_verbose || (errno != EPIPE && errno != ENOENT)) + if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT)) msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream)); } else { if (msg_verbose) diff --git a/gnu/dist/postfix/src/global/mail_version.h b/gnu/dist/postfix/src/global/mail_version.h index 1110a99a2df..da59f417ab3 100644 --- a/gnu/dist/postfix/src/global/mail_version.h +++ b/gnu/dist/postfix/src/global/mail_version.h @@ -1,4 +1,4 @@ -/* $NetBSD: mail_version.h,v 1.1.1.26 2006/11/07 02:57:37 rpaulo Exp $ */ +/* $NetBSD: mail_version.h,v 1.1.1.27 2006/12/21 02:32:08 rpaulo Exp $ */ #ifndef _MAIL_VERSION_H_INCLUDED_ #define _MAIL_VERSION_H_INCLUDED_ @@ -22,8 +22,8 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20061101" -#define MAIL_VERSION_NUMBER "2.3.4" +#define MAIL_RELEASE_DATE "20061211" +#define MAIL_VERSION_NUMBER "2.3.5" #ifdef SNAPSHOT # define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff --git a/gnu/dist/postfix/src/global/pipe_command.c b/gnu/dist/postfix/src/global/pipe_command.c index b98e731b9d6..f3700238a6b 100644 --- a/gnu/dist/postfix/src/global/pipe_command.c +++ b/gnu/dist/postfix/src/global/pipe_command.c @@ -1,4 +1,4 @@ -/* $NetBSD: pipe_command.c,v 1.1.1.11 2006/07/19 01:17:27 rpaulo Exp $ */ +/* $NetBSD: pipe_command.c,v 1.1.1.12 2006/12/21 02:32:24 rpaulo Exp $ */ /*++ /* NAME @@ -635,7 +635,7 @@ int pipe_command(VSTREAM *src, DSN_BUF *why,...) "Command died with signal %d: \"%s\"%s%s", WTERMSIG(wait_status), args.command, log_len ? ". Command output: " : "", log_buf); - return (PIPE_STAT_BOUNCE); + return (PIPE_STAT_DEFER); } /* Use "D.S.N text" command output. XXX What diagnostic code? */ else if (dsn_valid(log_buf) > 0) { diff --git a/gnu/dist/postfix/src/global/resolve_clnt.c b/gnu/dist/postfix/src/global/resolve_clnt.c index 54f52fb671c..b660c308317 100644 --- a/gnu/dist/postfix/src/global/resolve_clnt.c +++ b/gnu/dist/postfix/src/global/resolve_clnt.c @@ -1,4 +1,4 @@ -/* $NetBSD: resolve_clnt.c,v 1.1.1.10 2006/07/19 01:17:28 rpaulo Exp $ */ +/* $NetBSD: resolve_clnt.c,v 1.1.1.11 2006/12/21 02:32:28 rpaulo Exp $ */ /*++ /* NAME @@ -166,6 +166,7 @@ void resolve_clnt(const char *class, const char *sender, const char *myname = "resolve_clnt"; VSTREAM *stream; int server_flags; + int count = 0; /* * One-entry cache. @@ -228,6 +229,7 @@ void resolve_clnt(const char *class, const char *sender, for (;;) { stream = clnt_stream_access(rewrite_clnt_stream); errno = 0; + count += 1; if (attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_REQ, class, ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender, @@ -241,7 +243,7 @@ void resolve_clnt(const char *class, const char *sender, ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient, ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &reply->flags, ATTR_TYPE_END) != 5) { - if (msg_verbose || (errno != EPIPE && errno != ENOENT)) + if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT)) msg_warn("problem talking to service %s: %m", var_rewrite_service); } else { diff --git a/gnu/dist/postfix/src/global/rewrite_clnt.c b/gnu/dist/postfix/src/global/rewrite_clnt.c index 69efbe238bc..6dcfec18629 100644 --- a/gnu/dist/postfix/src/global/rewrite_clnt.c +++ b/gnu/dist/postfix/src/global/rewrite_clnt.c @@ -1,4 +1,4 @@ -/* $NetBSD: rewrite_clnt.c,v 1.1.1.9 2006/07/19 01:17:28 rpaulo Exp $ */ +/* $NetBSD: rewrite_clnt.c,v 1.1.1.10 2006/12/21 02:32:29 rpaulo Exp $ */ /*++ /* NAME @@ -84,6 +84,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result) { VSTREAM *stream; int server_flags; + int count = 0; /* * One-entry cache. @@ -131,6 +132,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result) for (;;) { stream = clnt_stream_access(rewrite_clnt_stream); errno = 0; + count += 1; if (attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR, ATTR_TYPE_STR, MAIL_ATTR_RULE, rule, @@ -141,7 +143,7 @@ VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result) ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &server_flags, ATTR_TYPE_STR, MAIL_ATTR_ADDR, result, ATTR_TYPE_END) != 2) { - if (msg_verbose || (errno != EPIPE && errno != ENOENT)) + if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT)) msg_warn("problem talking to service %s: %m", var_rewrite_service); } else { diff --git a/gnu/dist/postfix/src/global/scache_clnt.c b/gnu/dist/postfix/src/global/scache_clnt.c index 0f90986ebd5..0124e0c9538 100644 --- a/gnu/dist/postfix/src/global/scache_clnt.c +++ b/gnu/dist/postfix/src/global/scache_clnt.c @@ -1,4 +1,4 @@ -/* $NetBSD: scache_clnt.c,v 1.1.1.2 2006/07/19 01:17:28 rpaulo Exp $ */ +/* $NetBSD: scache_clnt.c,v 1.1.1.3 2006/12/21 02:32:30 rpaulo Exp $ */ /*++ /* NAME @@ -93,6 +93,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl, VSTREAM *stream; int status; int tries; + int count = 0; if (msg_verbose) msg_info("%s: endp=%s prop=%s fd=%d", @@ -112,6 +113,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl, for (tries = 0; sp->auto_clnt != 0; tries++) { if ((stream = auto_clnt_access(sp->auto_clnt)) != 0) { errno = 0; + count += 1; if (attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_REQ, SCACHE_REQ_SAVE_ENDP, ATTR_TYPE_INT, MAIL_ATTR_TTL, endp_ttl, @@ -128,7 +130,7 @@ static void scache_clnt_save_endp(SCACHE *scache, int endp_ttl, || attr_scan(stream, ATTR_FLAG_STRICT, ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status, ATTR_TYPE_END) != 1) { - if (msg_verbose || (errno != EPIPE && errno != ENOENT)) + if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT)) msg_warn("problem talking to service %s: %m", VSTREAM_PATH(stream)); /* Give up or recover. */ @@ -283,7 +285,7 @@ static void scache_clnt_save_dest(SCACHE *scache, int dest_ttl, myname, status); break; } - } + } /* Give up or recover. */ if (tries >= SCACHE_MAX_TRIES - 1) { msg_warn("disabling connection caching"); diff --git a/gnu/dist/postfix/src/global/verify_clnt.c b/gnu/dist/postfix/src/global/verify_clnt.c index 9e81bb1c1cb..78b905fc011 100644 --- a/gnu/dist/postfix/src/global/verify_clnt.c +++ b/gnu/dist/postfix/src/global/verify_clnt.c @@ -1,4 +1,4 @@ -/* $NetBSD: verify_clnt.c,v 1.1.1.4 2006/07/19 01:17:29 rpaulo Exp $ */ +/* $NetBSD: verify_clnt.c,v 1.1.1.5 2006/12/21 02:32:36 rpaulo Exp $ */ /*++ /* NAME @@ -98,6 +98,7 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why) { VSTREAM *stream; int request_status; + int count = 0; /* * Do client-server plumbing. @@ -111,6 +112,7 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why) for (;;) { stream = clnt_stream_access(vrfy_clnt); errno = 0; + count += 1; if (attr_print(stream, ATTR_FLAG_NONE, ATTR_TYPE_STR, MAIL_ATTR_REQ, VRFY_REQ_QUERY, ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr, @@ -121,7 +123,7 @@ int verify_clnt_query(const char *addr, int *addr_status, VSTRING *why) ATTR_TYPE_INT, MAIL_ATTR_ADDR_STATUS, addr_status, ATTR_TYPE_STR, MAIL_ATTR_WHY, why, ATTR_TYPE_END) != 3) { - if (msg_verbose || (errno != EPIPE && errno != ENOENT)) + if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT)) msg_warn("problem talking to service %s: %m", var_verify_service); } else { diff --git a/gnu/dist/postfix/src/milter/milter8.c b/gnu/dist/postfix/src/milter/milter8.c index 5f9dfe20341..9f41054d2cf 100644 --- a/gnu/dist/postfix/src/milter/milter8.c +++ b/gnu/dist/postfix/src/milter/milter8.c @@ -1,4 +1,4 @@ -/* $NetBSD: milter8.c,v 1.1.1.2 2006/08/01 00:04:04 rpaulo Exp $ */ +/* $NetBSD: milter8.c,v 1.1.1.3 2006/12/21 02:32:56 rpaulo Exp $ */ /*++ /* NAME @@ -860,6 +860,7 @@ static const char *milter8_event(MILTER8 *milter, int event, int skip_reply, ARGV *macros,...) { + const char *myname = "milter8_event"; va_list ap; ssize_t data_len; int err; @@ -874,6 +875,17 @@ static const char *milter8_event(MILTER8 *milter, int event, #define DONT_SKIP_REPLY 0 /* + * Sanity check. + */ + if (milter->fp == 0 || milter->def_reply != 0) { + msg_warn("%s: attempt to send event %s to milter %s after error", + myname, + (smfic_name = str_name_code(smfic_table, event)) != 0 ? + smfic_name : "(unknown MTA event)", milter->m.name); + return (milter->def_reply); + } + + /* * Skip this event if it doesn't exist in the protocol that I announced. */ #ifndef USE_LIBMILTER_INCLUDES @@ -1187,7 +1199,7 @@ static const char *milter8_event(MILTER8 *milter, int event, (ssize_t) index, STR(milter->buf)); if (edit_resp) - return (milter8_def_reply(milter, edit_resp)); + return (edit_resp); continue; #endif @@ -1205,7 +1217,7 @@ static const char *milter8_event(MILTER8 *milter, int event, STR(milter->buf), STR(milter->body)); if (edit_resp) - return (milter8_def_reply(milter, edit_resp)); + return (edit_resp); continue; /* @@ -1234,7 +1246,7 @@ static const char *milter8_event(MILTER8 *milter, int event, STR(milter->buf), STR(milter->body)); if (edit_resp) - return (milter8_def_reply(milter, edit_resp)); + return (edit_resp); continue; #endif @@ -1250,7 +1262,7 @@ static const char *milter8_event(MILTER8 *milter, int event, edit_resp = parent->add_rcpt(parent->chg_context, STR(milter->buf)); if (edit_resp) - return (milter8_def_reply(milter, edit_resp)); + return (edit_resp); continue; /* @@ -1265,7 +1277,7 @@ static const char *milter8_event(MILTER8 *milter, int event, edit_resp = parent->del_rcpt(parent->chg_context, STR(milter->buf)); if (edit_resp) - return (milter8_def_reply(milter, edit_resp)); + return (edit_resp); continue; /* @@ -1282,7 +1294,7 @@ static const char *milter8_event(MILTER8 *milter, int event, edit_resp = parent->repl_body(parent->chg_context, milter->body); if (edit_resp) - return (milter8_def_reply(milter, edit_resp)); + return (edit_resp); continue; #endif } @@ -1930,6 +1942,16 @@ static void milter8_header(void *ptr, int unused_header_class, int skip_reply; /* + * XXX Workaround: mime_state_update() may invoke multiple call-backs + * before returning to the caller. + */ +#define MILTER8_MESSAGE_DONE(milter, msg_ctx) \ + ((milter)->state != MILTER8_STAT_MESSAGE || (msg_ctx)->resp != 0) + + if (MILTER8_MESSAGE_DONE(milter, msg_ctx)) + return; + + /* * XXX Sendmail compatibility. Don't expose our first (received) header * to mail filter applications. See also cleanup_milter.c for code to * ensure that header replace requests are relative to the message @@ -1992,6 +2014,8 @@ static void milter8_eoh(void *ptr) MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr; MILTER8 *milter = msg_ctx->milter; + if (MILTER8_MESSAGE_DONE(milter, msg_ctx)) + return; if (msg_verbose) msg_info("%s: eoh milter %s", myname, milter->m.name); msg_ctx->resp = @@ -2014,6 +2038,9 @@ static void milter8_body(void *ptr, int rec_type, ssize_t space; ssize_t count; + if (MILTER8_MESSAGE_DONE(milter, msg_ctx)) + return; + /* * XXX Sendmail compatibility: don't expose our first body line. */ @@ -2081,6 +2108,8 @@ static void milter8_eob(void *ptr) MILTER_MSG_CONTEXT *msg_ctx = (MILTER_MSG_CONTEXT *) ptr; MILTER8 *milter = msg_ctx->milter; + if (MILTER8_MESSAGE_DONE(milter, msg_ctx)) + return; if (msg_verbose) msg_info("%s: eob milter %s", myname, milter->m.name); msg_ctx->resp = @@ -2146,7 +2175,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile, /* * XXX When the message (not MIME body part) does not end in CRLF - * (i.e. the last record was REC_TYPE_CONT), do we send CRLF + * (i.e. the last record was REC_TYPE_CONT), do we send a CRLF * terminator before triggering the end-of-body condition? */ for (;;) { @@ -2166,9 +2195,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile, msg_ctx.resp = "450 4.3.0 Queue file write error"; break; } - if (msg_ctx.resp != 0) - break; - if (milter->state != MILTER8_STAT_MESSAGE) + if (MILTER8_MESSAGE_DONE(milter, &msg_ctx)) break; if (rec_type != REC_TYPE_NORM && rec_type != REC_TYPE_CONT) break; diff --git a/gnu/dist/postfix/src/oqmgr/qmgr_entry.c b/gnu/dist/postfix/src/oqmgr/qmgr_entry.c index 3f01ca325a4..e5d44077ca5 100644 --- a/gnu/dist/postfix/src/oqmgr/qmgr_entry.c +++ b/gnu/dist/postfix/src/oqmgr/qmgr_entry.c @@ -1,4 +1,4 @@ -/* $NetBSD: qmgr_entry.c,v 1.1.1.4 2006/07/19 01:17:34 rpaulo Exp $ */ +/* $NetBSD: qmgr_entry.c,v 1.1.1.5 2006/12/21 02:33:00 rpaulo Exp $ */ /*++ /* NAME @@ -239,7 +239,7 @@ void qmgr_entry_done(QMGR_ENTRY *entry, int which) #define FUDGE(x) ((x) * (var_qmgr_fudge / 100.0)) message->refcount--; if (message->rcpt_offset > 0 - && qmgr_recipient_count < FUDGE(var_qmgr_rcpt_limit)) + && qmgr_recipient_count < FUDGE(var_qmgr_rcpt_limit) - 100) qmgr_message_realloc(message); if (message->refcount == 0) qmgr_active_done(message); diff --git a/gnu/dist/postfix/src/qmgr/qmgr_job.c b/gnu/dist/postfix/src/qmgr/qmgr_job.c index b3ab6c076f2..cd6abee2bd8 100644 --- a/gnu/dist/postfix/src/qmgr/qmgr_job.c +++ b/gnu/dist/postfix/src/qmgr/qmgr_job.c @@ -1,4 +1,4 @@ -/* $NetBSD: qmgr_job.c,v 1.1.1.3 2006/07/19 01:17:38 rpaulo Exp $ */ +/* $NetBSD: qmgr_job.c,v 1.1.1.4 2006/12/21 02:33:21 rpaulo Exp $ */ /*++ /* NAME @@ -765,6 +765,16 @@ static QMGR_PEER *qmgr_job_peer_select(QMGR_JOB *job) QMGR_PEER *peer; QMGR_MESSAGE *message = job->message; + /* + * Workaround to prevent queue manager starvation until the last slow + * batch of multi-recipient mail is finished. Postfix 2.4 has a final + * solution, but that involves major changes. + */ + if (message->rcpt_offset != 0 + && message->rcpt_limit > message->rcpt_count + 100 + && message->refcount > 0) { + qmgr_message_realloc(message); + } if (HAS_ENTRIES(job) && (peer = qmgr_peer_select(job)) != 0) return (peer); diff --git a/gnu/dist/postfix/src/smtp/smtp_chat.c b/gnu/dist/postfix/src/smtp/smtp_chat.c index ca585a764a1..b714947bc40 100644 --- a/gnu/dist/postfix/src/smtp/smtp_chat.c +++ b/gnu/dist/postfix/src/smtp/smtp_chat.c @@ -1,4 +1,4 @@ -/* $NetBSD: smtp_chat.c,v 1.1.1.10 2006/07/19 01:17:43 rpaulo Exp $ */ +/* $NetBSD: smtp_chat.c,v 1.1.1.11 2006/12/21 02:33:34 rpaulo Exp $ */ /*++ /* NAME @@ -307,7 +307,8 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session) */ session->error_mask |= MAIL_ERROR_PROTOCOL; if (session->features & SMTP_FEATURE_PIPELINING) { - msg_warn("non-%s response from %s: %.100s", + msg_warn("%s: non-%s response from %s: %.100s", + session->state->request->queue_id, (session->state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP", session->namaddrport, STR(session->buffer)); diff --git a/gnu/dist/postfix/src/smtp/smtp_proto.c b/gnu/dist/postfix/src/smtp/smtp_proto.c index 9beaa265316..f8aa18e40be 100644 --- a/gnu/dist/postfix/src/smtp/smtp_proto.c +++ b/gnu/dist/postfix/src/smtp/smtp_proto.c @@ -1,4 +1,4 @@ -/* $NetBSD: smtp_proto.c,v 1.1.1.13 2006/11/07 02:58:41 rpaulo Exp $ */ +/* $NetBSD: smtp_proto.c,v 1.1.1.14 2006/12/21 02:33:38 rpaulo Exp $ */ /*++ /* NAME @@ -1016,6 +1016,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state, } while (0) #define RETURN(x) do { \ + if (recv_state != SMTP_STATE_LAST) \ + DONT_CACHE_THIS_SESSION; \ vstring_free(next_command); \ if (survivors) \ myfree((char *) survivors); \ @@ -1634,7 +1636,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state, session->mime_state = mime_state_alloc(downgrading ? MIME_OPT_DOWNGRADE | MIME_OPT_REPORT_NESTING : - MIME_OPT_REPORT_NESTING, + MIME_OPT_DISABLE_MIME, smtp_generic_maps ? smtp_header_rewrite : smtp_header_out, diff --git a/gnu/dist/postfix/src/util/msg.c b/gnu/dist/postfix/src/util/msg.c index 545c9c6c9da..bf4881dc26b 100644 --- a/gnu/dist/postfix/src/util/msg.c +++ b/gnu/dist/postfix/src/util/msg.c @@ -1,4 +1,4 @@ -/* $NetBSD: msg.c,v 1.1.1.4 2006/07/19 01:17:53 rpaulo Exp $ */ +/* $NetBSD: msg.c,v 1.1.1.5 2006/12/21 02:35:05 rpaulo Exp $ */ /*++ /* NAME @@ -41,7 +41,7 @@ /* to the standard error stream, but the disposition can be changed /* by the user. See the hints below in the SEE ALSO section. /* -/* msg_info(), msg_warn(), msg_error(), msg_fatal() and msg_panic() +/* msg_info(), msg_warn(), msg_error(), msg_fatal*() and msg_panic() /* produce a one-line record with the program name, a severity code /* (except for msg_info()), and an informative message. The program /* name must have been set by calling one of the msg_XXX_init() @@ -74,6 +74,40 @@ /* msg_verbose is a global flag that can be set to make software /* more verbose about what it is doing. By default the flag is zero. /* By convention, a larger value means more noise. +/* REENTRANCY +/* .ad +/* .fi +/* The msg_info() etc. output routines are protected against +/* ordinary recursive calls and against re-entry by signal +/* handlers. +/* +/* Protection against re-entry by signal handlers is subject +/* to the following limitations: +/* .IP \(bu +/* The signal handlers must never return. In other words, the +/* signal handlers must do one or more of the following: call +/* _exit(), kill the process with a signal, and permanently block +/* the process. +/* .IP \(bu +/* The signal handlers must invoke msg_info() etc. not until +/* after the msg_XXX_init() functions complete initialization, +/* and not until after the first formatted output to a VSTRING +/* or VSTREAM. +/* .IP \(bu +/* Each msg_cleanup() call-back function, and each Postfix or +/* system function invoked by that call-back function, either +/* protects itself against recursive calls and re-entry by a +/* terminating signal handler, or is called exclusively by the +/* msg(3) module. +/* .PP +/* When re-entrancy is detected, the requested output and +/* optional cleanup operations are skipped. Skipping the output +/* operations prevents memory corruption of VSTREAM_ERR data +/* structures, and prevents deadlock on Linux releases that +/* use mutexes within system library routines such as syslog(). +/* This protection exists under the condition that these +/* specific resources are accessed exclusively via the msg_info() +/* etc. functions. /* SEE ALSO /* msg_output(3) specify diagnostics disposition /* msg_stdio(3) direct diagnostics to standard I/O stream @@ -120,14 +154,23 @@ int msg_verbose = 0; /* - * Private state. The msg_exiting flag prevents us from recursively - * reporting an error. + * Private state. */ static MSG_CLEANUP_FN msg_cleanup_fn = 0; -static int msg_exiting = 0; static int msg_error_count = 0; static int msg_error_bound = 13; + /* + * The msg_exiting flag prevents us from recursively reporting an error with + * msg_fatal*() or msg_panic(), and provides a first-level safety net for + * optional cleanup actions against signal handler re-entry problems. Note + * that msg_vprintf() implements its own guard against re-entry. + * + * XXX We specify global scope, to discourage the compiler from doing smart + * things. + */ +volatile int msg_exiting = 0; + /* msg_info - report informative message */ void msg_info(const char *fmt,...) @@ -177,7 +220,8 @@ NORETURN msg_fatal(const char *fmt,...) msg_cleanup_fn(); } sleep(1); - exit(1); + /* In case we're running as a signal handler. */ + _exit(1); } /* msg_fatal_status - report error and terminate gracefully */ @@ -194,7 +238,8 @@ NORETURN msg_fatal_status(int status, const char *fmt,...) msg_cleanup_fn(); } sleep(1); - exit(status); + /* In case we're running as a signal handler. */ + _exit(status); } /* msg_panic - report error and dump core */ @@ -210,7 +255,8 @@ NORETURN msg_panic(const char *fmt,...) } sleep(1); abort(); /* Die! */ - exit(1); /* DIE!! */ + /* In case we're running as a signal handler. */ + _exit(1); /* DIE!! */ } /* msg_cleanup - specify cleanup routine */ diff --git a/gnu/dist/postfix/src/util/msg_output.c b/gnu/dist/postfix/src/util/msg_output.c index aaeb302b737..f4d7c73bda2 100644 --- a/gnu/dist/postfix/src/util/msg_output.c +++ b/gnu/dist/postfix/src/util/msg_output.c @@ -1,4 +1,4 @@ -/* $NetBSD: msg_output.c,v 1.1.1.2 2004/05/31 00:25:00 heas Exp $ */ +/* $NetBSD: msg_output.c,v 1.1.1.3 2006/12/21 02:35:05 rpaulo Exp $ */ /*++ /* NAME @@ -42,6 +42,36 @@ /* /* msg_text() copies a pre-formatted text, sanitizes the result, and /* calls the output handlers registered with msg_output(). +/* REENTRANCY +/* .ad +/* .fi +/* The above output routines are protected against ordinary +/* recursive calls and against re-entry by signal +/* handlers, with the following limitations: +/* .IP \(bu +/* The signal handlers must never return. In other words, the +/* signal handlers must do one or more of the following: call +/* _exit(), kill the process with a signal, and permanently +/* block the process. +/* .IP \(bu +/* The signal handlers must call the above output routines not +/* until after msg_output() completes initialization, and not +/* until after the first formatted output to a VSTRING or +/* VSTREAM. +/* .IP \(bu +/* Each msg_output() call-back function, and each Postfix or +/* system function called by that call-back function, either +/* must protect itself against recursive calls and re-entry +/* by a terminating signal handler, or it must be called +/* exclusively by functions in the msg_output(3) module. +/* .PP +/* When re-entrancy is detected, the requested output operation +/* is skipped. This prevents memory corruption of VSTREAM_ERR +/* data structures, and prevents deadlock on Linux releases +/* that use mutexes within system library routines such as +/* syslog(). This protection exists under the condition that +/* these specific resources are accessed exclusively via +/* msg_output() call-back functions. /* LICENSE /* .ad /* .fi @@ -70,6 +100,12 @@ #include <msg_output.h> /* + * Global scope, to discourage the compiler from doing smart things. + */ +volatile int msg_vprintf_lock; +volatile int msg_text_lock; + + /* * Private state. */ static MSG_OUTPUT_FN *msg_output_fn = 0; @@ -82,6 +118,12 @@ void msg_output(MSG_OUTPUT_FN output_fn) { /* + * Allocate all resources during initialization. + */ + if (msg_buffer == 0) + msg_buffer = vstring_alloc(100); + + /* * We're not doing this often, so avoid complexity and allocate memory * for an exact fit. */ @@ -108,10 +150,13 @@ void msg_printf(int level, const char *format,...) void msg_vprintf(int level, const char *format, va_list ap) { - if (msg_buffer == 0) - msg_buffer = vstring_alloc(100); - vstring_vsprintf(msg_buffer, percentm(format, errno), ap); - msg_text(level, vstring_str(msg_buffer)); + if (msg_vprintf_lock == 0) { + msg_vprintf_lock = 1; + /* OK if terminating signal handler hijacks control before next stmt. */ + vstring_vsprintf(msg_buffer, percentm(format, errno), ap); + msg_text(level, vstring_str(msg_buffer)); + msg_vprintf_lock = 0; + } } /* msg_text - sanitize and log pre-formatted text */ @@ -123,13 +168,17 @@ void msg_text(int level, const char *text) /* * Sanitize the text. Use a private copy if necessary. */ - if (msg_buffer == 0) - msg_buffer = vstring_alloc(100); - if (text != vstring_str(msg_buffer)) - vstring_strcpy(msg_buffer, text); - printable(vstring_str(msg_buffer), '?'); - if (msg_output_fn_count == 0) - msg_vstream_init("unknown", VSTREAM_ERR); - for (i = 0; i < msg_output_fn_count; i++) - msg_output_fn[i] (level, vstring_str(msg_buffer)); + if (msg_text_lock == 0) { + msg_text_lock = 1; + /* OK if terminating signal handler hijacks control before next stmt. */ + if (text != vstring_str(msg_buffer)) + vstring_strcpy(msg_buffer, text); + printable(vstring_str(msg_buffer), '?'); + /* On-the-fly initialization for debugging test programs only. */ + if (msg_output_fn_count == 0) + msg_vstream_init("unknown", VSTREAM_ERR); + for (i = 0; i < msg_output_fn_count; i++) + msg_output_fn[i] (level, vstring_str(msg_buffer)); + msg_text_lock = 0; + } } diff --git a/gnu/dist/postfix/src/util/vbuf_print.c b/gnu/dist/postfix/src/util/vbuf_print.c index 7853f210878..66e862a0c66 100644 --- a/gnu/dist/postfix/src/util/vbuf_print.c +++ b/gnu/dist/postfix/src/util/vbuf_print.c @@ -1,4 +1,4 @@ -/* $NetBSD: vbuf_print.c,v 1.1.1.4 2006/07/19 01:17:56 rpaulo Exp $ */ +/* $NetBSD: vbuf_print.c,v 1.1.1.5 2006/12/21 02:35:19 rpaulo Exp $ */ /*++ /* NAME @@ -22,6 +22,18 @@ /* In addition, vbuf_print() recognizes the %m format specifier /* and expands it to the error message corresponding to the current /* value of the global \fIerrno\fR variable. +/* REENTRANCY +/* .ad +/* .fi +/* vbuf_print() allocates a static buffer. After completion +/* of the first vbuf_print() call, this buffer is safe for +/* reentrant vbuf_print() calls by (asynchronous) terminating +/* signal handlers or by (synchronous) terminating error +/* handlers. vbuf_print() initialization typically happens +/* upon the first formatted output to a VSTRING or VSTREAM. +/* +/* However, it is up to the caller to ensure that the destination +/* VSTREAM or VSTRING buffer is protected against reentrant usage. /* LICENSE /* .ad /* .fi |
