diff --git a/postfix/HISTORY b/postfix/HISTORY index 55b3c66dc..c90407813 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -13663,3 +13663,14 @@ Apologies for any names omitted. Cleanup: adjust the VSTREAM buffer strategy when reusing an SMTP connection with a large TCP MSS value. File: smtp/smtp_reuse.c. + +20090419 + + Bugfix: don't re-enable SIGHUP if it is ignored in the + parent. This may cause random "Postfix integrity check + failed" errors at boot time (POSIX SIGHUP death), causing + Postfix not to start. We duplicate code from postdrop and + thus avoid past mistakes. File: postsuper/postsuper.c. + + Robustness: don't re-enable SIGTERM if it is ignored in the + parent. Files: postsuper/postsuper.c, postdrop/postdrop.c. diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 281bda442..4a79c60bd 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,8 +20,8 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20090103" -#define MAIL_VERSION_NUMBER "2.4.10" +#define MAIL_RELEASE_DATE "20090511" +#define MAIL_VERSION_NUMBER "2.4.11" #ifdef SNAPSHOT # define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE diff --git a/postfix/src/postdrop/postdrop.c b/postfix/src/postdrop/postdrop.c index 92170708f..4a0e073cf 100644 --- a/postfix/src/postdrop/postdrop.c +++ b/postfix/src/postdrop/postdrop.c @@ -340,7 +340,8 @@ int main(int argc, char **argv) signal(SIGINT, postdrop_sig); signal(SIGQUIT, postdrop_sig); - signal(SIGTERM, postdrop_sig); + if (signal(SIGTERM, SIG_IGN) == SIG_DFL) + signal(SIGTERM, postdrop_sig); if (signal(SIGHUP, SIG_IGN) == SIG_DFL) signal(SIGHUP, postdrop_sig); msg_cleanup(postdrop_cleanup); diff --git a/postfix/src/postsuper/postsuper.c b/postfix/src/postsuper/postsuper.c index 65172d08a..c4425e6de 100644 --- a/postfix/src/postsuper/postsuper.c +++ b/postfix/src/postsuper/postsuper.c @@ -968,11 +968,17 @@ static void interrupted(int sig) /* * This commands requires root privileges. We therefore do not worry * about hostile signals, and report problems via msg_warn(). + * + * We use the in-kernel SIGINT handler address as an atomic variable to + * prevent nested interrupted() calls. For this reason, main() must + * configure interrupted() as SIGINT handler before other signal handlers + * are allowed to invoke interrupted(). See also similar code in + * postdrop. */ - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) { - (void) signal(SIGINT, SIG_IGN); + if (signal(SIGINT, SIG_IGN) != SIG_IGN) { (void) signal(SIGQUIT, SIG_IGN); (void) signal(SIGTERM, SIG_IGN); + (void) signal(SIGHUP, SIG_IGN); if (inode_mismatch > 0 || inode_fixed > 0 || position_mismatch > 0) msg_warn("OPERATION INCOMPLETE -- RERUN COMMAND TO FIX THE QUEUE FIRST"); if (sig) @@ -1169,11 +1175,20 @@ int main(int argc, char **argv) * * Set up signal handlers after permanently dropping super-user privileges, * so that signal handlers will always run with the correct privileges. + * + * XXX Don't enable SIGHUP or SIGTERM if it was ignored by the parent. + * + * interrupted() uses the in-kernel SIGINT handler address as an atomic + * variable to prevent nested interrupted() calls. For this reason, the + * SIGINT handler must be configured before other signal handlers are + * allowed to invoke interrupted(). See also similar code in postdrop. */ - signal(SIGHUP, interrupted); signal(SIGINT, interrupted); signal(SIGQUIT, interrupted); - signal(SIGTERM, interrupted); + if (signal(SIGTERM, SIG_IGN) == SIG_DFL) + signal(SIGTERM, interrupted); + if (signal(SIGHUP, SIG_IGN) == SIG_DFL) + signal(SIGHUP, interrupted); msg_cleanup(fatal_warning); /*