am-utils-6.2-1.git.e03592f0 - fix debug log deadlock From: Ian Kent It's possible (and likely) a SIGCHLD signal can arrive while in syslog(2) and also attempt log log a message leading to deadlock. --- libamu/xutil.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/libamu/xutil.c b/libamu/xutil.c index b3e3a0f..0d9d2ec 100644 --- a/libamu/xutil.c +++ b/libamu/xutil.c @@ -420,14 +420,33 @@ debug_option(char *opt) void dplog(const char *fmt, ...) { +#ifdef HAVE_SIGACTION + sigset_t old, chld; +#else /* not HAVE_SIGACTION */ + int mask; +#endif /* not HAVE_SIGACTION */ va_list ap; +#ifdef HAVE_SIGACTION + sigemptyset(&chld); + sigaddset(&chld, SIGCHLD); +#else /* not HAVE_SIGACTION */ + mask = sigblock(sigmask(SIGCHLD)); +#endif /* not HAVE_SIGACTION */ + + sigprocmask(SIG_BLOCK, &chld, &old); if (!logfp) logfp = stderr; /* initialize before possible first use */ va_start(ap, fmt); real_plog(XLOG_DEBUG, fmt, ap); va_end(ap); + +#ifdef HAVE_SIGACTION + sigprocmask(SIG_SETMASK, &old, NULL); +#else /* not HAVE_SIGACTION */ + mask = sigblock(sigmask(SIGCHLD)); +#endif /* not HAVE_SIGACTION */ } #endif /* DEBUG */ @@ -435,14 +454,33 @@ dplog(const char *fmt, ...) void plog(int lvl, const char *fmt, ...) { +#ifdef HAVE_SIGACTION + sigset_t old, chld; +#else /* not HAVE_SIGACTION */ + int mask; +#endif /* not HAVE_SIGACTION */ va_list ap; +#ifdef HAVE_SIGACTION + sigemptyset(&chld); + sigaddset(&chld, SIGCHLD); + sigprocmask(SIG_BLOCK, &chld, &old); +#else /* not HAVE_SIGACTION */ + mask = sigblock(sigmask(SIGCHLD)); +#endif /* not HAVE_SIGACTION */ + if (!logfp) logfp = stderr; /* initialize before possible first use */ va_start(ap, fmt); real_plog(lvl, fmt, ap); va_end(ap); + +#ifdef HAVE_SIGACTION + sigprocmask(SIG_SETMASK, &old, NULL); +#else /* not HAVE_SIGACTION */ + sigsetmask(mask); +#endif /* not HAVE_SIGACTION */ }