Commit 4f14a906 4f14a906311f8f650a12c8a697bc57a37f2096fa by Sergey Poznyakoff

Fix mailbox corruption in imap4d.

Delivery of a signal when a previous signal was being handled caused
mailbox corruption.

* imap4d/imap4d.c (imap4d_child_signal_setup): New function.
(imap4d_mainloop): Call imap4d_child_signal_setup.
* imap4d/signal.c (imap4d_child_signal): Reset all signal handlers
before doing actual job.
* lib/signal.c (mu_set_signals): Use sigaction.
1 parent 7cbbb401
......@@ -383,18 +383,22 @@ get_client_address (int fd, struct sockaddr_in *pcs)
return 0;
}
void
imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo))
{
static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM };
mu_set_signals (handler, sigtab, MU_ARRAY_SIZE (sigtab));
}
static int
imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
{
imap4d_tokbuf_t tokp;
char *text;
int debug_mode = isatty (fd);
static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM };
/* Reset signals */
mu_set_signals (imap4d_child_signal, sigtab, MU_ARRAY_SIZE (sigtab));
imap4d_child_signal_setup (imap4d_child_signal);
util_setio (infile, outfile);
if (imap4d_preauth_setup (fd) == 0)
......
......@@ -49,21 +49,25 @@ imap4d_master_signal (int signo)
RETSIGTYPE
imap4d_child_signal (int signo)
{
imap4d_child_signal_setup (SIG_IGN);
mu_diag_output (MU_DIAG_CRIT, _("got signal `%s'"), strsignal (signo));
switch (signo)
{
case SIGTERM:
case SIGHUP:
imap4d_bye (ERR_TERMINATE);
signo = ERR_TERMINATE;
break;
case SIGALRM:
imap4d_bye (ERR_TIMEOUT);
signo = ERR_TIMEOUT;
break;
case SIGPIPE:
imap4d_bye (ERR_NO_OFILE);
signo = ERR_NO_OFILE;
break;
default:
imap4d_bye (ERR_SIGNAL);
signo = ERR_SIGNAL;
}
imap4d_bye (signo);
}
......
......@@ -26,7 +26,16 @@ void
mu_set_signals (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc)
{
int i;
struct sigaction act;
act.sa_flags = 0;
sigemptyset (&act.sa_mask);
for (i = 0; i < sigc; i++)
signal (sigv[i], handler);
sigaddset (&act.sa_mask, i);
for (i = 0; i < sigc; i++)
{
act.sa_handler = handler;
sigaction (sigv[i], &act, NULL);
}
}
......