diff options
| author | Gergely Nagy <algernon@balabit.hu> | 2012-03-24 17:18:12 +0100 |
|---|---|---|
| committer | Gergely Nagy <algernon@balabit.hu> | 2012-03-24 17:18:12 +0100 |
| commit | d6fbe492d6dd7a1648134ef26ee22a83c5ad6365 (patch) | |
| tree | 8217cd5c0f57c3d13a4d8889213c10f89c88ef5a | |
| parent | edd3b75417caafeb1c6476c2958a970d8f799437 (diff) | |
| download | libumberlog-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.c | 21 |
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 |
