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.
Showing
3 changed files
with
28 additions
and
11 deletions
... | @@ -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 | } | ... | ... |
-
Please register or sign in to post a comment