83 lines
1.9 KiB
Diff
83 lines
1.9 KiB
Diff
am-utils-6.2-1.git.e03592f0 - fix debug log deadlock
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
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 */
|
|
}
|
|
|
|
|