diff options
author | teor <teor@torproject.org> | 2020-02-12 12:47:15 +1000 |
---|---|---|
committer | teor <teor@torproject.org> | 2020-02-13 00:00:41 +1000 |
commit | 3d1ef3b6f89e760b4340ba77e0b3db1246dc5c80 (patch) | |
tree | 2cc62a0f4ed8a74f60ae4b57533f3fe93008d751 /src/lib/err | |
parent | e0ea7407a4370c977ebbf0b70712c9e5ff7937fa (diff) | |
download | tor-3d1ef3b6f89e760b4340ba77e0b3db1246dc5c80.tar.gz tor-3d1ef3b6f89e760b4340ba77e0b3db1246dc5c80.zip |
err/log: Stop closing stderr and stdout during shutdown
Closing these file descriptors can hide sanitiser logs.
Instead, flush the logs before tor exits, using fsync().
Some Windows environments don't have fsync(), so we check
for it at compile time.
Fixes bug 33087; bugfix on 0.4.1.6.
Diffstat (limited to 'src/lib/err')
-rw-r--r-- | src/lib/err/torerr.c | 26 | ||||
-rw-r--r-- | src/lib/err/torerr.h | 2 | ||||
-rw-r--r-- | src/lib/err/torerr_sys.c | 6 |
3 files changed, 15 insertions, 19 deletions
diff --git a/src/lib/err/torerr.c b/src/lib/err/torerr.c index 92ef80e56a..c2dd862e11 100644 --- a/src/lib/err/torerr.c +++ b/src/lib/err/torerr.c @@ -151,29 +151,27 @@ tor_log_reset_sigsafe_err_fds(void) } /** - * Close the list of fds that get errors from inside a signal handler or + * Flush the list of fds that get errors from inside a signal handler or * other emergency condition. These fds are shared with the logging code: - * closing them flushes the log buffers, and prevents any further logging. + * flushing them also flushes the log buffers. * - * This function closes stderr, so it should only be called immediately before - * process shutdown. + * This function is safe to call during signal handlers. */ void -tor_log_close_sigsafe_err_fds(void) +tor_log_flush_sigsafe_err_fds(void) { + /* If we don't have fsync() in unistd.h, we can't flush the logs. */ +#ifdef HAVE_FSYNC int n_fds, i; const int *fds = NULL; n_fds = tor_log_get_sigsafe_err_fds(&fds); for (i = 0; i < n_fds; ++i) { - /* tor_log_close_sigsafe_err_fds_on_error() is called on error and on - * shutdown, so we can't log or take any useful action if close() - * fails. */ - (void)close(fds[i]); + /* This function is called on error and on shutdown, so we don't log, or + * take any other action, if fsync() fails. */ + (void)fsync(fds[i]); } - - /* Don't even try logging, we've closed all the log fds. */ - tor_log_set_sigsafe_err_fds(NULL, 0); +#endif } /** @@ -217,13 +215,13 @@ tor_raw_assertion_failed_msg_(const char *file, int line, const char *expr, /** * Call the abort() function to kill the current process with a fatal - * error. But first, close the raw error file descriptors, so error messages + * error. But first, flush the raw error file descriptors, so error messages * are written before process termination. **/ void tor_raw_abort_(void) { - tor_log_close_sigsafe_err_fds(); + tor_log_flush_sigsafe_err_fds(); abort(); } diff --git a/src/lib/err/torerr.h b/src/lib/err/torerr.h index f5b36eef9c..ce1b049c47 100644 --- a/src/lib/err/torerr.h +++ b/src/lib/err/torerr.h @@ -40,7 +40,7 @@ void tor_log_err_sigsafe(const char *m, ...); int tor_log_get_sigsafe_err_fds(const int **out); void tor_log_set_sigsafe_err_fds(const int *fds, int n); void tor_log_reset_sigsafe_err_fds(void); -void tor_log_close_sigsafe_err_fds(void); +void tor_log_flush_sigsafe_err_fds(void); void tor_log_sigsafe_err_set_granularity(int ms); void tor_raw_abort_(void) ATTR_NORETURN; diff --git a/src/lib/err/torerr_sys.c b/src/lib/err/torerr_sys.c index aa49ba36bd..46fc853550 100644 --- a/src/lib/err/torerr_sys.c +++ b/src/lib/err/torerr_sys.c @@ -27,11 +27,9 @@ subsys_torerr_initialize(void) static void subsys_torerr_shutdown(void) { - /* Stop handling signals with backtraces, then close the logs. */ + /* Stop handling signals with backtraces, then flush the logs. */ clean_up_backtrace_handler(); - /* We can't log any log messages after this point: we've closed all the log - * fds, including stdio. */ - tor_log_close_sigsafe_err_fds(); + tor_log_flush_sigsafe_err_fds(); } const subsys_fns_t sys_torerr = { |