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) ...@@ -383,18 +383,22 @@ get_client_address (int fd, struct sockaddr_in *pcs)
383 return 0; 383 return 0;
384 } 384 }
385 385
386 void
387 imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo))
388 {
389 static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
390 SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM };
391 mu_set_signals (handler, sigtab, MU_ARRAY_SIZE (sigtab));
392 }
393
386 static int 394 static int
387 imap4d_mainloop (int fd, FILE *infile, FILE *outfile) 395 imap4d_mainloop (int fd, FILE *infile, FILE *outfile)
388 { 396 {
389 imap4d_tokbuf_t tokp; 397 imap4d_tokbuf_t tokp;
390 char *text; 398 char *text;
391 int debug_mode = isatty (fd); 399 int debug_mode = isatty (fd);
392 static int sigtab[] = { SIGILL, SIGBUS, SIGFPE, SIGSEGV, SIGSTOP, SIGPIPE,
393 SIGABRT, SIGINT, SIGQUIT, SIGTERM, SIGHUP, SIGALRM };
394
395 /* Reset signals */
396 mu_set_signals (imap4d_child_signal, sigtab, MU_ARRAY_SIZE (sigtab));
397 400
401 imap4d_child_signal_setup (imap4d_child_signal);
398 util_setio (infile, outfile); 402 util_setio (infile, outfile);
399 403
400 if (imap4d_preauth_setup (fd) == 0) 404 if (imap4d_preauth_setup (fd) == 0)
......
...@@ -49,21 +49,25 @@ imap4d_master_signal (int signo) ...@@ -49,21 +49,25 @@ imap4d_master_signal (int signo)
49 RETSIGTYPE 49 RETSIGTYPE
50 imap4d_child_signal (int signo) 50 imap4d_child_signal (int signo)
51 { 51 {
52 imap4d_child_signal_setup (SIG_IGN);
52 mu_diag_output (MU_DIAG_CRIT, _("got signal `%s'"), strsignal (signo)); 53 mu_diag_output (MU_DIAG_CRIT, _("got signal `%s'"), strsignal (signo));
53
54 switch (signo) 54 switch (signo)
55 { 55 {
56 case SIGTERM: 56 case SIGTERM:
57 case SIGHUP: 57 case SIGHUP:
58 imap4d_bye (ERR_TERMINATE); 58 signo = ERR_TERMINATE;
59 break;
59 60
60 case SIGALRM: 61 case SIGALRM:
61 imap4d_bye (ERR_TIMEOUT); 62 signo = ERR_TIMEOUT;
63 break;
62 64
63 case SIGPIPE: 65 case SIGPIPE:
64 imap4d_bye (ERR_NO_OFILE); 66 signo = ERR_NO_OFILE;
67 break;
65 68
66 default: 69 default:
67 imap4d_bye (ERR_SIGNAL); 70 signo = ERR_SIGNAL;
68 } 71 }
72 imap4d_bye (signo);
69 } 73 }
......
...@@ -26,7 +26,16 @@ void ...@@ -26,7 +26,16 @@ void
26 mu_set_signals (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc) 26 mu_set_signals (RETSIGTYPE (*handler) (int signo), int *sigv, int sigc)
27 { 27 {
28 int i; 28 int i;
29 struct sigaction act;
29 30
31 act.sa_flags = 0;
32 sigemptyset (&act.sa_mask);
30 for (i = 0; i < sigc; i++) 33 for (i = 0; i < sigc; i++)
31 signal (sigv[i], handler); 34 sigaddset (&act.sa_mask, i);
35
36 for (i = 0; i < sigc; i++)
37 {
38 act.sa_handler = handler;
39 sigaction (sigv[i], &act, NULL);
40 }
32 } 41 }
......