Unverified Commit 3d1ef3b6 authored by teor's avatar teor
Browse files

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.
parent e0ea7407
Loading
Loading
Loading
Loading

changes/bug33087

0 → 100644
+7 −0
Original line number Diff line number Diff line
  o Minor bugfixes (logging):
    - Stop closing stderr and stdout during shutdown. Closing these file
      descriptors can hide sanitiser logs.
      Fixes bug 33087; bugfix on 0.4.1.6.
    - Flush stderr, stdout, and file logs during shutdown, if supported by the
      OS. This change helps make sure that any final logs are recorded.
      Fixes bug 33087; bugfix on 0.4.1.6.
+1 −0
Original line number Diff line number Diff line
@@ -649,6 +649,7 @@ AC_CHECK_FUNCS(
	explicit_bzero \
	timingsafe_memcmp \
	flock \
	fsync \
	ftime \
	get_current_dir_name \
	getaddrinfo \
+12 −14
Original line number Diff line number Diff line
@@ -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();
}

+1 −1
Original line number Diff line number Diff line
@@ -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;
+2 −4
Original line number Diff line number Diff line
@@ -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 = {
Loading