From 6b97a5a843341b5ea2a9039bdd5290d524a44cd4 Mon Sep 17 00:00:00 2001 From: teor Date: Wed, 4 Sep 2019 14:50:09 +1000 Subject: [PATCH 1/6] backtrace: Disable signal handlers in remove_bt_handler() Fixes bug 31614; bugfix on 0.2.5.2-alpha. --- src/lib/err/backtrace.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/lib/err/backtrace.c b/src/lib/err/backtrace.c index 1d1b3bcfa3..77dc6b8cbf 100644 --- a/src/lib/err/backtrace.c +++ b/src/lib/err/backtrace.c @@ -190,13 +190,15 @@ dump_stack_symbols_to_error_fds(void) backtrace_symbols_fd(cb_buf, (int)depth, fds[i]); } +/* The signals that we want our backtrace handler to trap */ +static int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, + SIGIO, -1 }; + /** Install signal handlers as needed so that when we crash, we produce a * useful stack trace. Return 0 on success, -errno on failure. */ static int install_bt_handler(const char *software) { - int trap_signals[] = { SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, - SIGIO, -1 }; int i, rv=0; strncpy(bt_version, software, sizeof(bt_version) - 1); @@ -235,6 +237,19 @@ install_bt_handler(const char *software) static void remove_bt_handler(void) { + int i; + + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigfillset(&sa.sa_mask); + + for (i = 0; trap_signals[i] >= 0; ++i) { + /* remove_bt_handler() is called on shutdown, from low-level code. + * It's not a fatal error, so we just ignore it. */ + (void)sigaction(trap_signals[i], &sa, NULL); + } } #endif /* defined(USE_BACKTRACE) */ From ab7bfdf40402449d6a2214e1dd5bc3fe5bc9a2e7 Mon Sep 17 00:00:00 2001 From: teor Date: Mon, 9 Sep 2019 11:21:15 +1000 Subject: [PATCH 2/6] backtrace: Add a missing check for HAVE_PTHREAD_H before using mutexes Fixes bug 31614; bugfix on 0.2.5.2-alpha. --- src/lib/err/backtrace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/err/backtrace.c b/src/lib/err/backtrace.c index 77dc6b8cbf..bf833c1621 100644 --- a/src/lib/err/backtrace.c +++ b/src/lib/err/backtrace.c @@ -57,7 +57,8 @@ #include "lib/err/torerr.h" #if defined(HAVE_EXECINFO_H) && defined(HAVE_BACKTRACE) && \ - defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) + defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION) && \ + defined(HAVE_PTHREAD_H) #define USE_BACKTRACE #endif From 315f14c709d019c55731faedb19a97b771f9c42f Mon Sep 17 00:00:00 2001 From: teor Date: Fri, 20 Sep 2019 11:40:05 +1000 Subject: [PATCH 3/6] backtrace: avoid undefined behaviour on re-initialisation cb_buf_mutex is statically initialised, so we can not destroy it when we are shutting down the err subsystem. If we destroy it, and then re-initialise tor, all our backtraces will fail. Part of 31736, but committed in this branch to avoid merge conflicts. --- src/lib/err/backtrace.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/err/backtrace.c b/src/lib/err/backtrace.c index bf833c1621..2a956e6115 100644 --- a/src/lib/err/backtrace.c +++ b/src/lib/err/backtrace.c @@ -251,6 +251,10 @@ remove_bt_handler(void) * It's not a fatal error, so we just ignore it. */ (void)sigaction(trap_signals[i], &sa, NULL); } + + /* cb_buf_mutex is statically initialised, so we can not destroy it. + * If we destroy it, and then re-initialise tor, all our backtraces will + * fail. */ } #endif /* defined(USE_BACKTRACE) */ From c9c046c365f10f5cbffada921931413edc690dbe Mon Sep 17 00:00:00 2001 From: teor Date: Thu, 26 Sep 2019 12:09:56 +1000 Subject: [PATCH 4/6] changes: file for 31614 --- changes/bug31614 | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 changes/bug31614 diff --git a/changes/bug31614 b/changes/bug31614 new file mode 100644 index 0000000000..c425a9fcd4 --- /dev/null +++ b/changes/bug31614 @@ -0,0 +1,9 @@ + o Minor bugfixes (logging): + - Disable backtrace signal handlers when shutting down tor. + Fixes bug 31614; bugfix on 0.2.5.2-alpha. + - Add a missing check for HAVE_PTHREAD_H, because the backtrace code uses + mutexes. Fixes bug 31614; bugfix on 0.2.5.2-alpha. + o Documentation: + - Explain why we can't destroy the backtrace buffer mutex. Explain why + we don't need to destroy the log mutex. + Closes ticket 31736. From 2f8a9a2db692a101b7e6241cbcdf9ed87841310b Mon Sep 17 00:00:00 2001 From: teor Date: Tue, 24 Sep 2019 13:51:38 +1000 Subject: [PATCH 5/6] sandbox: Allow backtrace signals to be disabled Part of 31614. --- src/lib/sandbox/sandbox.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/sandbox/sandbox.c b/src/lib/sandbox/sandbox.c index e2356a1720..5c02c012e8 100644 --- a/src/lib/sandbox/sandbox.c +++ b/src/lib/sandbox/sandbox.c @@ -295,6 +295,7 @@ sb_rt_sigaction(scmp_filter_ctx ctx, sandbox_cfg_t *filter) unsigned i; int rc; int param[] = { SIGINT, SIGTERM, SIGPIPE, SIGUSR1, SIGUSR2, SIGHUP, SIGCHLD, + SIGSEGV, SIGILL, SIGFPE, SIGBUS, SIGSYS, SIGIO, #ifdef SIGXFSZ SIGXFSZ #endif From 749c2e1761c753992fb2549e7ee912e568f563d6 Mon Sep 17 00:00:00 2001 From: teor Date: Thu, 26 Sep 2019 12:18:23 +1000 Subject: [PATCH 6/6] log: explain why it is safe to leave the log mutex initialized The log mutex is dynamically initialized, guarded by log_mutex_initialized. We don't want to destroy it, because after it is destroyed, we won't see any more logs. If tor is re-initialized, log_mutex_initialized will still be 1. So we won't trigger any undefined behaviour by trying to re-initialize the log mutex. Part of 31736, but committed in this branch to avoid merge conflicts. --- src/lib/log/log.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/log/log.c b/src/lib/log/log.c index a9ad38fb25..eacd413a53 100644 --- a/src/lib/log/log.c +++ b/src/lib/log/log.c @@ -804,7 +804,10 @@ logs_free_all(void) } /* We _could_ destroy the log mutex here, but that would screw up any logs - * that happened between here and the end of execution. */ + * that happened between here and the end of execution. + * If tor is re-initialized, log_mutex_initialized will still be 1. So we + * won't trigger any undefined behaviour by trying to re-initialize the + * log mutex. */ } /** Remove and free the log entry victim from the linked-list