summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGergely Nagy <algernon@balabit.hu>2012-03-24 17:18:12 +0100
committerGergely Nagy <algernon@balabit.hu>2012-03-24 17:18:12 +0100
commitd6fbe492d6dd7a1648134ef26ee22a83c5ad6365 (patch)
tree8217cd5c0f57c3d13a4d8889213c10f89c88ef5a
parentedd3b75417caafeb1c6476c2958a970d8f799437 (diff)
downloadlibumberlog-d6fbe492d6dd7a1648134ef26ee22a83c5ad6365.tar.gz
libumberlog-d6fbe492d6dd7a1648134ef26ee22a83c5ad6365.tar.xz
libumberlog-d6fbe492d6dd7a1648134ef26ee22a83c5ad6365.zip
Fix infinite recursion on FreeBSD.
On FreeBSD, syslog() calls vsyslog(), our own replacement version. So when from syslog(), we call our vsyslog(), which calls the old syslog(), that ends up calling our own vsyslog() again. To work around this issue, use a thread-local static variable that signals whether we're recursing, and if we are, then call the old vsyslog from the new one, thus breaking the loop. This makes the library function correctly on FreeBSD too. Signed-off-by: Gergely Nagy <algernon@balabit.hu>
-rw-r--r--lib/umberlog.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/lib/umberlog.c b/lib/umberlog.c
index e2d72de..ae9ebaf 100644
--- a/lib/umberlog.c
+++ b/lib/umberlog.c
@@ -45,8 +45,10 @@
#if __USE_FORTIFY_LEVEL > 0
static void (*old_syslog_chk) ();
+static void (*old_vsyslog_chk) ();
#else
static void (*old_syslog) ();
+static void (*old_vsyslog) ();
#endif
static void (*old_openlog) ();
@@ -67,13 +69,17 @@ static __thread struct
char hostname[_POSIX_HOST_NAME_MAX + 1];
} ul_sys_settings;
+static __thread int ul_recurse;
+
static void
ul_init (void)
{
#if __USE_FORTIFY_LEVEL > 0
old_syslog_chk = dlsym (RTLD_NEXT, "__syslog_chk");
+ old_vsyslog_chk = dlsym (RTLD_NEXT, "__vsyslog_chk");
#else
old_syslog = dlsym (RTLD_NEXT, "syslog");
+ old_vsyslog = dlsym (RTLD_NEXT, "vsyslog");
#endif
old_openlog = dlsym (RTLD_NEXT, "openlog");
old_setlogmask = dlsym (RTLD_NEXT, "setlogmask");
@@ -388,7 +394,20 @@ ul_vsyslog (int priority, const char *msg_format, va_list ap)
void
ul_legacy_vsyslog (int priority, const char *msg_format, va_list ap)
{
- _ul_vsyslog (0, priority, msg_format, ap);
+ if (ul_recurse)
+ {
+#if __USE_FORTIFY_LEVEL > 0
+ old_vsyslog_chk (priority, __USE_FORTIFY_LEVEL - 1, msg_format, ap);
+#else
+ old_vsyslog (priority, msg_format, ap);
+#endif
+ }
+ else
+ {
+ ul_recurse = 1;
+ _ul_vsyslog (0, priority, msg_format, ap);
+ }
+ ul_recurse = 0;
}
void