diff options
Diffstat (limited to 'src')
37 files changed, 358 insertions, 102 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c index b4bccd9351..bdfa547fd7 100644 --- a/src/app/config/config.c +++ b/src/app/config/config.c @@ -61,7 +61,7 @@ #define CONFIG_PRIVATE #include "core/or/or.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "app/config/statefile.h" #include "app/main/main.h" #include "app/main/subsysmgr.h" diff --git a/src/app/config/statefile.c b/src/app/config/statefile.c index bcc06809b3..552bd2c443 100644 --- a/src/app/config/statefile.c +++ b/src/app/config/statefile.c @@ -32,7 +32,7 @@ #include "core/or/or.h" #include "core/or/circuitstats.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "core/mainloop/mainloop.h" #include "core/mainloop/netstatus.h" #include "core/mainloop/connection.h" diff --git a/src/core/include.am b/src/core/include.am index 914c370ec1..9b4b251c81 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -9,7 +9,6 @@ endif # ADD_C_FILE: INSERT SOURCES HERE. LIBTOR_APP_A_SOURCES = \ src/app/config/config.c \ - src/app/config/confparse.c \ src/app/config/statefile.c \ src/app/main/main.c \ src/app/main/shutdown.c \ @@ -214,7 +213,6 @@ src_core_libtor_app_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) # ADD_C_FILE: INSERT HEADERS HERE. noinst_HEADERS += \ src/app/config/config.h \ - src/app/config/confparse.h \ src/app/config/or_options_st.h \ src/app/config/or_state_st.h \ src/app/config/statefile.h \ diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c index ff809c01cf..1daf468715 100644 --- a/src/core/or/circuitbuild.c +++ b/src/core/or/circuitbuild.c @@ -30,7 +30,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "core/crypto/hs_ntor.h" #include "core/crypto/onion_crypto.h" #include "core/crypto/onion_fast.h" diff --git a/src/core/or/circuitstats.c b/src/core/or/circuitstats.c index 03eea1d779..7a7f3ca600 100644 --- a/src/core/or/circuitstats.c +++ b/src/core/or/circuitstats.c @@ -29,7 +29,7 @@ #include "core/or/circuitbuild.h" #include "core/or/circuitstats.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "feature/control/control_events.h" #include "lib/crypt_ops/crypto_rand.h" #include "core/mainloop/mainloop.h" diff --git a/src/feature/client/entrynodes.c b/src/feature/client/entrynodes.c index 54a9238d8f..36b575ef20 100644 --- a/src/feature/client/entrynodes.c +++ b/src/feature/client/entrynodes.c @@ -114,7 +114,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "app/config/statefile.h" #include "core/mainloop/connection.h" #include "core/mainloop/mainloop.h" @@ -3765,7 +3765,8 @@ guard_selection_get_err_str_if_dir_info_missing(guard_selection_t *gs, /* otherwise return a helpful error string */ tor_asprintf(&ret_str, "We're missing descriptors for %d/%d of our " - "primary entry guards (total %sdescriptors: %d/%d).", + "primary entry guards (total %sdescriptors: %d/%d). " + "That's ok. We will try to fetch missing descriptors soon.", n_missing_descriptors, num_primary_to_check, using_mds?"micro":"", num_present, num_usable); diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c index ad4a4ef0af..a1d7f825db 100644 --- a/src/feature/control/control_cmd.c +++ b/src/feature/control/control_cmd.c @@ -13,7 +13,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "app/main/main.h" #include "core/mainloop/connection.h" #include "core/or/circuitbuild.h" diff --git a/src/feature/dirauth/keypin.h b/src/feature/dirauth/keypin.h index 722b6ca5fc..ab2362b3f8 100644 --- a/src/feature/dirauth/keypin.h +++ b/src/feature/dirauth/keypin.h @@ -11,10 +11,25 @@ int keypin_check_and_add(const uint8_t *rsa_id_digest, const int replace_existing_entry); int keypin_check(const uint8_t *rsa_id_digest, const uint8_t *ed25519_id_key); +int keypin_close_journal(void); +#ifdef HAVE_MODULE_DIRAUTH int keypin_open_journal(const char *fname); -int keypin_close_journal(void); int keypin_load_journal(const char *fname); +#else +static inline int +keypin_open_journal(const char *fname) +{ + (void)fname; + return 0; +} +static inline int +keypin_load_journal(const char *fname) +{ + (void)fname; + return 0; +} +#endif void keypin_clear(void); int keypin_check_lone_rsa(const uint8_t *rsa_id_digest); @@ -44,4 +59,3 @@ MOCK_DECL(STATIC void, keypin_add_entry_to_map, (keypin_ent_t *ent)); #endif /* defined(KEYPIN_PRIVATE) */ #endif /* !defined(TOR_KEYPIN_H) */ - diff --git a/src/feature/dirauth/process_descs.h b/src/feature/dirauth/process_descs.h index 1d4085b091..184caa18b8 100644 --- a/src/feature/dirauth/process_descs.h +++ b/src/feature/dirauth/process_descs.h @@ -12,10 +12,13 @@ #ifndef TOR_RECV_UPLOADS_H #define TOR_RECV_UPLOADS_H -int dirserv_load_fingerprint_file(void); +// for was_router_added_t. +#include "feature/nodelist/routerlist.h" + void dirserv_free_fingerprint_list(void); -int dirserv_add_own_fingerprint(crypto_pk_t *pk); +#ifdef HAVE_MODULE_DIRAUTH +int dirserv_load_fingerprint_file(void); enum was_router_added_t dirserv_add_multiple_descriptors( const char *desc, size_t desclen, uint8_t purpose, @@ -25,16 +28,86 @@ enum was_router_added_t dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source); +int dirserv_would_reject_router(const routerstatus_t *rs); int authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg, int complain, int *valid_out); +int dirserv_add_own_fingerprint(crypto_pk_t *pk); uint32_t dirserv_router_get_status(const routerinfo_t *router, const char **msg, int severity); void dirserv_set_node_flags_from_authoritative_status(node_t *node, uint32_t authstatus); - -int dirserv_would_reject_router(const routerstatus_t *rs); +#else +static inline int +dirserv_load_fingerprint_file(void) +{ + return 0; +} +static inline enum was_router_added_t +dirserv_add_multiple_descriptors(const char *desc, size_t desclen, + uint8_t purpose, + const char *source, + const char **msg) +{ + (void)desc; + (void)desclen; + (void)purpose; + (void)source; + (void)msg; + return (enum was_router_added_t)0; +} +static inline enum was_router_added_t +dirserv_add_descriptor(routerinfo_t *ri, + const char **msg, + const char *source) +{ + (void)ri; + (void)msg; + (void)source; + return (enum was_router_added_t)0; +} +static inline int +dirserv_would_reject_router(const routerstatus_t *rs) +{ + (void)rs; + return 0; +} +static inline int +authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg, + int complain, + int *valid_out) +{ + (void)ri; + (void)msg; + (void)complain; + (void)valid_out; + return 0; +} +static inline int +dirserv_add_own_fingerprint(crypto_pk_t *pk) +{ + (void)pk; + return 0; +} +static inline uint32_t +dirserv_router_get_status(const routerinfo_t *router, + const char **msg, + int severity) +{ + (void)router; + (void)msg; + (void)severity; + return 0; +} +static inline void +dirserv_set_node_flags_from_authoritative_status(node_t *node, + uint32_t authstatus) +{ + (void)node; + (void)authstatus; +} +#endif #ifdef TOR_UNIT_TESTS STATIC int dirserv_router_has_valid_address(routerinfo_t *ri); diff --git a/src/feature/dirauth/reachability.h b/src/feature/dirauth/reachability.h index 873a3f9a23..8a83f0c493 100644 --- a/src/feature/dirauth/reachability.h +++ b/src/feature/dirauth/reachability.h @@ -24,13 +24,36 @@ #define REACHABILITY_TEST_CYCLE_PERIOD \ (REACHABILITY_TEST_INTERVAL*REACHABILITY_MODULO_PER_TEST) +void dirserv_single_reachability_test(time_t now, routerinfo_t *router); +void dirserv_test_reachability(time_t now); + +#ifdef HAVE_MODULE_DIRAUTH +int dirserv_should_launch_reachability_test(const routerinfo_t *ri, + const routerinfo_t *ri_old); void dirserv_orconn_tls_done(const tor_addr_t *addr, uint16_t or_port, const char *digest_rcvd, const struct ed25519_public_key_t *ed_id_rcvd); -int dirserv_should_launch_reachability_test(const routerinfo_t *ri, - const routerinfo_t *ri_old); -void dirserv_single_reachability_test(time_t now, routerinfo_t *router); -void dirserv_test_reachability(time_t now); +#else +static inline int +dirserv_should_launch_reachability_test(const routerinfo_t *ri, + const routerinfo_t *ri_old) +{ + (void)ri; + (void)ri_old; + return 0; +} +static inline void +dirserv_orconn_tls_done(const tor_addr_t *addr, + uint16_t or_port, + const char *digest_rcvd, + const struct ed25519_public_key_t *ed_id_rcvd) +{ + (void)addr; + (void)or_port; + (void)digest_rcvd; + (void)ed_id_rcvd; +} +#endif #endif /* !defined(TOR_REACHABILITY_H) */ diff --git a/src/feature/dirauth/shared_random.c b/src/feature/dirauth/shared_random.c index 5ccf1a95e5..a45f0a29c3 100644 --- a/src/feature/dirauth/shared_random.c +++ b/src/feature/dirauth/shared_random.c @@ -90,7 +90,7 @@ #include "core/or/or.h" #include "feature/dirauth/shared_random.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "lib/crypt_ops/crypto_rand.h" #include "lib/crypt_ops/crypto_util.h" #include "feature/nodelist/networkstatus.h" diff --git a/src/feature/dirauth/shared_random_state.c b/src/feature/dirauth/shared_random_state.c index f2a626c738..76befb0f5f 100644 --- a/src/feature/dirauth/shared_random_state.c +++ b/src/feature/dirauth/shared_random_state.c @@ -12,7 +12,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "lib/crypt_ops/crypto_util.h" #include "feature/dirauth/dirvote.h" #include "feature/nodelist/networkstatus.h" diff --git a/src/feature/hs/hs_dos.c b/src/feature/hs/hs_dos.c index 0ae36017f8..19794e09d3 100644 --- a/src/feature/hs/hs_dos.c +++ b/src/feature/hs/hs_dos.c @@ -29,7 +29,7 @@ #include "lib/evloop/token_bucket.h" -#include "hs_dos.h" +#include "feature/hs/hs_dos.h" /* Default value of the allowed INTRODUCE2 cell rate per second. Above that * value per second, the introduction is denied. */ diff --git a/src/lib/confmgt/.may_include b/src/lib/confmgt/.may_include index d85dbf6904..2564133917 100644 --- a/src/lib/confmgt/.may_include +++ b/src/lib/confmgt/.may_include @@ -7,3 +7,5 @@ lib/encoding/*.h lib/log/*.h lib/malloc/*.h lib/string/*.h +lib/testsupport/*.h +ext/*.h diff --git a/src/app/config/confparse.c b/src/lib/confmgt/confparse.c index 9f7fdc5c35..08e562f654 100644 --- a/src/app/config/confparse.c +++ b/src/lib/confmgt/confparse.c @@ -23,7 +23,7 @@ #define CONFPARSE_PRIVATE #include "orconfig.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "lib/confmgt/structvar.h" #include "lib/confmgt/unitparse.h" diff --git a/src/app/config/confparse.h b/src/lib/confmgt/confparse.h index 054348d8d4..054348d8d4 100644 --- a/src/app/config/confparse.h +++ b/src/lib/confmgt/confparse.h diff --git a/src/lib/confmgt/include.am b/src/lib/confmgt/include.am index aa5b37fdb5..81cd868e5e 100644 --- a/src/lib/confmgt/include.am +++ b/src/lib/confmgt/include.am @@ -6,6 +6,7 @@ endif # ADD_C_FILE: INSERT SOURCES HERE. src_lib_libtor_confmgt_a_SOURCES = \ + src/lib/confmgt/confparse.c \ src/lib/confmgt/structvar.c \ src/lib/confmgt/type_defs.c \ src/lib/confmgt/typedvar.c \ @@ -18,6 +19,7 @@ src_lib_libtor_confmgt_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS) # ADD_C_FILE: INSERT HEADERS HERE. noinst_HEADERS += \ + src/lib/confmgt/confparse.h \ src/lib/confmgt/structvar.h \ src/lib/confmgt/type_defs.h \ src/lib/confmgt/typedvar.h \ diff --git a/src/lib/err/backtrace.c b/src/lib/err/backtrace.c index 75d5093c54..c2011285c0 100644 --- a/src/lib/err/backtrace.c +++ b/src/lib/err/backtrace.c @@ -172,7 +172,7 @@ crash_handler(int sig, siginfo_t *si, void *ctx_) for (i=0; i < n_fds; ++i) backtrace_symbols_fd(cb_buf, (int)depth, fds[i]); - abort(); + tor_raw_abort_(); } /** Write a backtrace to all of the emergency-error fds. */ diff --git a/src/lib/err/torerr.c b/src/lib/err/torerr.c index 48fcf35e06..0a4ee5d417 100644 --- a/src/lib/err/torerr.c +++ b/src/lib/err/torerr.c @@ -110,6 +110,14 @@ tor_log_get_sigsafe_err_fds(const int **out) * Update the list of fds that get errors from inside a signal handler or * other emergency condition. Ignore any beyond the first * TOR_SIGSAFE_LOG_MAX_FDS. + * + * These fds must remain open even after the log module has shut down. (And + * they should remain open even while logs are being reconfigured.) Therefore, + * any fds closed by the log module should be dup()ed, and the duplicate fd + * should be given to the err module in fds. In particular, the log module + * closes the file log fds, but does not close the stdio log fds. + * + * If fds is NULL or n is 0, clears the list of error fds. */ void tor_log_set_sigsafe_err_fds(const int *fds, int n) @@ -118,8 +126,18 @@ tor_log_set_sigsafe_err_fds(const int *fds, int n) n = TOR_SIGSAFE_LOG_MAX_FDS; } - memcpy(sigsafe_log_fds, fds, n * sizeof(int)); - n_sigsafe_log_fds = n; + /* Clear the entire array. This code mitigates against some race conditions, + * but there are still some races here: + * - err logs are disabled while the array is cleared, and + * - a thread can read the old value of n_sigsafe_log_fds, then read a + * partially written array. + * We could fix these races using atomics, but atomics use the err module. */ + n_sigsafe_log_fds = 0; + memset(sigsafe_log_fds, 0, sizeof(sigsafe_log_fds)); + if (fds && n > 0) { + memcpy(sigsafe_log_fds, fds, n * sizeof(int)); + n_sigsafe_log_fds = n; + } } /** @@ -133,6 +151,32 @@ tor_log_reset_sigsafe_err_fds(void) } /** + * Close 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. + * + * This function closes stderr, so it should only be called immediately before + * process shutdown. + */ +void +tor_log_close_sigsafe_err_fds(void) +{ + 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]); + } + + /* Don't even try logging, we've closed all the log fds. */ + tor_log_set_sigsafe_err_fds(NULL, 0); +} + +/** * Set the granularity (in ms) to use when reporting fatal errors outside * the logging system. */ @@ -171,6 +215,18 @@ tor_raw_assertion_failed_msg_(const char *file, int line, const char *expr, tor_log_err_sigsafe_write("\n"); } +/** + * Call the abort() function to kill the current process with a fatal + * error. But first, close the raw error file descriptors, so error messages + * are written before process termination. + **/ +void +tor_raw_abort_(void) +{ + tor_log_close_sigsafe_err_fds(); + abort(); +} + /* As format_{hex,dex}_number_sigsafe, but takes a <b>radix</b> argument * in range 2..16 inclusive. */ static int @@ -205,7 +261,7 @@ format_number_sigsafe(unsigned long x, char *buf, int buf_len, unsigned digit = (unsigned) (x % radix); if (cp <= buf) { /* Not tor_assert(); see above. */ - abort(); + tor_raw_abort_(); } --cp; *cp = "0123456789ABCDEF"[digit]; @@ -214,7 +270,7 @@ format_number_sigsafe(unsigned long x, char *buf, int buf_len, /* NOT tor_assert; see above. */ if (cp != buf) { - abort(); // LCOV_EXCL_LINE + tor_raw_abort_(); // LCOV_EXCL_LINE } return len; diff --git a/src/lib/err/torerr.h b/src/lib/err/torerr.h index c2da6697a9..0e839cb1ba 100644 --- a/src/lib/err/torerr.h +++ b/src/lib/err/torerr.h @@ -20,13 +20,13 @@ #define raw_assert(expr) STMT_BEGIN \ if (!(expr)) { \ tor_raw_assertion_failed_msg_(__FILE__, __LINE__, #expr, NULL); \ - abort(); \ + tor_raw_abort_(); \ } \ STMT_END #define raw_assert_unreached(expr) raw_assert(0) #define raw_assert_unreached_msg(msg) STMT_BEGIN \ tor_raw_assertion_failed_msg_(__FILE__, __LINE__, "0", (msg)); \ - abort(); \ + tor_raw_abort_(); \ STMT_END void tor_raw_assertion_failed_msg_(const char *file, int line, @@ -40,8 +40,11 @@ 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_sigsafe_err_set_granularity(int ms); +void tor_raw_abort_(void) ATTR_NORETURN; + int format_hex_number_sigsafe(unsigned long x, char *buf, int max_len); int format_dec_number_sigsafe(unsigned long x, char *buf, int max_len); diff --git a/src/lib/err/torerr_sys.c b/src/lib/err/torerr_sys.c index 34f70f1f0b..eb818004fb 100644 --- a/src/lib/err/torerr_sys.c +++ b/src/lib/err/torerr_sys.c @@ -27,8 +27,11 @@ subsys_torerr_initialize(void) static void subsys_torerr_shutdown(void) { - tor_log_reset_sigsafe_err_fds(); + /* Stop handling signals with backtraces, then close 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(); } const subsys_fns_t sys_torerr = { diff --git a/src/lib/log/log.c b/src/lib/log/log.c index 56f016eae4..be6f459554 100644 --- a/src/lib/log/log.c +++ b/src/lib/log/log.c @@ -225,6 +225,7 @@ int log_global_min_severity_ = LOG_NOTICE; static void delete_log(logfile_t *victim); static void close_log(logfile_t *victim); +static void close_log_sigsafe(logfile_t *victim); static char *domain_to_string(log_domain_mask_t domain, char *buf, size_t buflen); @@ -665,13 +666,24 @@ tor_log_update_sigsafe_err_fds(void) const logfile_t *lf; int found_real_stderr = 0; - int fds[TOR_SIGSAFE_LOG_MAX_FDS]; + /* log_fds and err_fds contain matching entries: log_fds are the fds used by + * the log module, and err_fds are the fds used by the err module. + * For stdio logs, the log_fd and err_fd values are identical, + * and the err module closes the fd on shutdown. + * For file logs, the err_fd is a dup() of the log_fd, + * and the log and err modules both close their respective fds on shutdown. + * (Once all fds representing a file are closed, the underlying file is + * closed.) + */ + int log_fds[TOR_SIGSAFE_LOG_MAX_FDS]; + int err_fds[TOR_SIGSAFE_LOG_MAX_FDS]; int n_fds; LOCK_LOGS(); /* Reserve the first one for stderr. This is safe because when we daemonize, - * we dup2 /dev/null to stderr, */ - fds[0] = STDERR_FILENO; + * we dup2 /dev/null to stderr. + * For stderr, log_fds and err_fds are the same. */ + log_fds[0] = err_fds[0] = STDERR_FILENO; n_fds = 1; for (lf = logfiles; lf; lf = lf->next) { @@ -685,25 +697,39 @@ tor_log_update_sigsafe_err_fds(void) (LD_BUG|LD_GENERAL)) { if (lf->fd == STDERR_FILENO) found_real_stderr = 1; - /* Avoid duplicates */ - if (int_array_contains(fds, n_fds, lf->fd)) + /* Avoid duplicates by checking the log module fd against log_fds */ + if (int_array_contains(log_fds, n_fds, lf->fd)) continue; - fds[n_fds++] = lf->fd; + /* Update log_fds using the log module's fd */ + log_fds[n_fds] = lf->fd; + if (lf->needs_close) { + /* File log fds are duplicated, because close_log() closes the log + * module's fd, and tor_log_close_sigsafe_err_fds() closes the err + * module's fd. Both refer to the same file. */ + err_fds[n_fds] = dup(lf->fd); + } else { + /* stdio log fds are not closed by the log module. + * tor_log_close_sigsafe_err_fds() closes stdio logs. */ + err_fds[n_fds] = lf->fd; + } + n_fds++; if (n_fds == TOR_SIGSAFE_LOG_MAX_FDS) break; } } if (!found_real_stderr && - int_array_contains(fds, n_fds, STDOUT_FILENO)) { + int_array_contains(log_fds, n_fds, STDOUT_FILENO)) { /* Don't use a virtual stderr when we're also logging to stdout. */ raw_assert(n_fds >= 2); /* Don't tor_assert inside log fns */ - fds[0] = fds[--n_fds]; + --n_fds; + log_fds[0] = log_fds[n_fds]; + err_fds[0] = err_fds[n_fds]; } UNLOCK_LOGS(); - tor_log_set_sigsafe_err_fds(fds, n_fds); + tor_log_set_sigsafe_err_fds(err_fds, n_fds); } /** Add to <b>out</b> a copy of every currently configured log file name. Used @@ -809,6 +835,30 @@ logs_free_all(void) * that happened between here and the end of execution. */ } +/** Close signal-safe log files. + * Closing the log files makes the process and OS flush log buffers. + * + * This function is safe to call from a signal handler. It should only be + * called when shutting down the log or err modules. It is currenly called + * by the err module, when terminating the process on an abnormal condition. + */ +void +logs_close_sigsafe(void) +{ + logfile_t *victim, *next; + /* We can't LOCK_LOGS() in a signal handler, because it may call + * signal-unsafe functions. And we can't deallocate memory, either. */ + next = logfiles; + logfiles = NULL; + while (next) { + victim = next; + next = next->next; + if (victim->needs_close) { + close_log_sigsafe(victim); + } + } +} + /** Remove and free the log entry <b>victim</b> from the linked-list * logfiles (it is probably present, but it might not be due to thread * racing issues). After this function is called, the caller shouldn't @@ -835,13 +885,26 @@ delete_log(logfile_t *victim) } /** Helper: release system resources (but not memory) held by a single - * logfile_t. */ + * signal-safe logfile_t. If the log's resources can not be released in + * a signal handler, does nothing. */ static void -close_log(logfile_t *victim) +close_log_sigsafe(logfile_t *victim) { if (victim->needs_close && victim->fd >= 0) { + /* We can't do anything useful here if close() fails: we're shutting + * down logging, and the err module only does fatal errors. */ close(victim->fd); victim->fd = -1; + } +} + +/** Helper: release system resources (but not memory) held by a single + * logfile_t. */ +static void +close_log(logfile_t *victim) +{ + if (victim->needs_close) { + close_log_sigsafe(victim); } else if (victim->is_syslog) { #ifdef HAVE_SYSLOG_H if (--syslog_count == 0) { diff --git a/src/lib/log/log.h b/src/lib/log/log.h index c4a27782c3..4291418eb6 100644 --- a/src/lib/log/log.h +++ b/src/lib/log/log.h @@ -173,6 +173,7 @@ void logs_set_domain_logging(int enabled); int get_min_log_level(void); void switch_logs_debug(void); void logs_free_all(void); +void logs_close_sigsafe(void); void add_temp_log(int min_severity); void close_temp_logs(void); void rollback_log_changes(void); diff --git a/src/lib/log/util_bug.c b/src/lib/log/util_bug.c index 76b97c1a08..0e99be35a4 100644 --- a/src/lib/log/util_bug.c +++ b/src/lib/log/util_bug.c @@ -11,6 +11,7 @@ #include "lib/log/util_bug.h" #include "lib/log/log.h" #include "lib/err/backtrace.h" +#include "lib/err/torerr.h" #ifdef TOR_UNIT_TESTS #include "lib/smartlist_core/smartlist_core.h" #include "lib/smartlist_core/smartlist_foreach.h" @@ -161,16 +162,18 @@ tor_bug_occurred_(const char *fname, unsigned int line, } /** - * Call the abort() function to kill the current process with a fatal - * error. + * Call the tor_raw_abort_() function to close raw logs, then kill the current + * process with a fatal error. But first, close the file-based log file + * descriptors, so error messages are written before process termination. * * (This is a separate function so that we declare it in util_bug.h without - * including stdlib in all the users of util_bug.h) + * including torerr.h in all the users of util_bug.h) **/ void tor_abort_(void) { - abort(); + logs_close_sigsafe(); + tor_raw_abort_(); } #ifdef _WIN32 diff --git a/src/lib/malloc/map_anon.c b/src/lib/malloc/map_anon.c index 0f6a4150c7..ae4edff769 100644 --- a/src/lib/malloc/map_anon.c +++ b/src/lib/malloc/map_anon.c @@ -27,6 +27,9 @@ #include <windows.h> #endif +#include <string.h> +#include <errno.h> + /** * Macro to get the high bytes of a size_t, if there are high bytes. * Windows needs this; other operating systems define a size_t that does @@ -108,7 +111,17 @@ static int nodump_mem(void *mem, size_t sz) { #if defined(MADV_DONTDUMP) - return madvise(mem, sz, MADV_DONTDUMP); + int rv = madvise(mem, sz, MADV_DONTDUMP); + if (rv == 0) { + return 0; + } else if (errno == ENOSYS || errno == EINVAL) { + return 0; // syscall not supported, or flag not supported. + } else { + tor_log_err_sigsafe("Unexpected error from madvise: ", + strerror(errno), + NULL); + return -1; + } #else (void) mem; (void) sz; @@ -136,18 +149,33 @@ noinherit_mem(void *mem, size_t sz, inherit_res_t *inherit_result_out) return 0; } #endif /* defined(FLAG_ZERO) */ + #ifdef FLAG_NOINHERIT int r2 = MINHERIT(mem, sz, FLAG_NOINHERIT); if (r2 == 0) { *inherit_result_out = INHERIT_RES_DROP; + return 0; } - return r2; -#else /* !(defined(FLAG_NOINHERIT)) */ +#endif /* defined(FLAG_NOINHERIT) */ + +#if defined(FLAG_ZERO) || defined(FLAG_NOINHERIT) + /* At least one operation was tried, and neither succeeded. */ + + if (errno == ENOSYS || errno == EINVAL) { + /* Syscall not supported, or flag not supported. */ + return 0; + } else { + tor_log_err_sigsafe("Unexpected error from minherit: ", + strerror(errno), + NULL); + return -1; + } +#else (void)inherit_result_out; (void)mem; (void)sz; return 0; -#endif /* defined(FLAG_NOINHERIT) */ +#endif } /** diff --git a/src/test/test_addr.c b/src/test/test_addr.c index 0f50a43615..f99e3be8f5 100644 --- a/src/test/test_addr.c +++ b/src/test/test_addr.c @@ -731,10 +731,6 @@ test_addr_ip6_helpers(void *arg) #define TEST_ADDR_PARSE_FMT(addr_str, expect_family, fmt_decorated, \ expect_str) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ - char buf[TOR_ADDR_BUF_LEN]; \ - const char *sv; \ r = tor_addr_parse(&addr, addr_str); \ tt_int_op(r, OP_EQ, expect_family); \ sv = tor_addr_to_str(buf, &addr, sizeof(buf), fmt_decorated); \ @@ -747,8 +743,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_ADDR_PARSE_XFAIL(addr_str) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ r = tor_addr_parse(&addr, addr_str); \ tt_int_op(r, OP_EQ, -1); \ tt_assert(tor_addr_is_null(&addr)); \ @@ -762,11 +756,6 @@ test_addr_ip6_helpers(void *arg) #define TEST_ADDR_PORT_PARSE_FMT(addr_port_str, default_port, expect_family, \ fmt_decorated, expect_str, expect_port) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ - uint16_t port; \ - char buf[TOR_ADDR_BUF_LEN]; \ - const char *sv; \ r = tor_addr_port_parse(LOG_DEBUG, addr_port_str, &addr, &port, \ default_port); \ tt_int_op(r, OP_EQ, 0); \ @@ -783,9 +772,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_ADDR_PORT_PARSE_XFAIL(addr_port_str, default_port) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ - uint16_t port; \ r = tor_addr_port_parse(LOG_DEBUG, addr_port_str, &addr, &port, \ default_port); \ tt_int_op(r, OP_EQ, -1); \ @@ -799,8 +785,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_ADDR_V4_LOOKUP_HOSTNAME(addr_str, expect_str) \ STMT_BEGIN \ - int r; \ - uint32_t addr32h; \ r = tor_lookup_hostname(addr_str, &addr32h); \ tt_int_op(r, OP_EQ, 0); \ tt_str_op(fmt_addr32(addr32h), OP_EQ, expect_str); \ @@ -812,8 +796,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_ADDR_V4_LOOKUP_XFAIL(bad_str) \ STMT_BEGIN \ - int r; \ - uint32_t addr32h; \ r = tor_lookup_hostname(bad_str, &addr32h); \ tt_int_op(r, OP_EQ, -1); \ tt_int_op(addr32h, OP_EQ, 0); \ @@ -828,8 +810,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_HOST_V4_LOOKUP(host_str) \ STMT_BEGIN \ - int r; \ - uint32_t addr32h; \ r = tor_lookup_hostname(host_str, &addr32h); \ tt_int_op(r, OP_GE, -1); \ tt_int_op(r, OP_LE, 1); \ @@ -845,10 +825,6 @@ test_addr_ip6_helpers(void *arg) #define TEST_ADDR_LOOKUP_FMT(addr_str, require_family, expect_family, \ fmt_decorated, expect_str) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ - char buf[TOR_ADDR_BUF_LEN]; \ - const char *sv; \ r = tor_addr_lookup(addr_str, require_family, &addr); \ tt_int_op(r, OP_EQ, 0); \ tt_int_op(tor_addr_family(&addr), OP_EQ, expect_family); \ @@ -863,8 +839,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_ADDR_LOOKUP_XFAIL(bad_str, require_family) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ r = tor_addr_lookup(bad_str, require_family, &addr); \ tt_int_op(r, OP_EQ, -1); \ tt_assert(tor_addr_is_null(&addr)); \ @@ -879,8 +853,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_HOST_LOOKUP(host_str, require_family) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ r = tor_addr_lookup(host_str, require_family, &addr); \ tt_int_op(r, OP_GE, -1); \ tt_int_op(r, OP_LE, 1); \ @@ -897,11 +869,6 @@ test_addr_ip6_helpers(void *arg) #define TEST_ADDR_PORT_LOOKUP_FMT(addr_port_str, expect_family, \ fmt_decorated, expect_str, expect_port) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ - uint16_t port; \ - char buf[TOR_ADDR_BUF_LEN]; \ - const char *sv; \ r = tor_addr_port_lookup(addr_port_str, &addr, &port); \ tt_int_op(r, OP_EQ, 0); \ tt_int_op(tor_addr_family(&addr), OP_EQ, expect_family); \ @@ -918,9 +885,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_ADDR_PORT_LOOKUP_XFAIL(bad_str) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ - uint16_t port; \ r = tor_addr_port_lookup(bad_str, &addr, &port); \ tt_int_op(r, OP_EQ, -1); \ tt_assert(tor_addr_is_null(&addr)); \ @@ -939,9 +903,6 @@ test_addr_ip6_helpers(void *arg) */ #define TEST_HOST_PORT_LOOKUP(host_port_str, expect_success_port) \ STMT_BEGIN \ - int r; \ - tor_addr_t addr; \ - uint16_t port; \ r = tor_addr_port_lookup(host_port_str, &addr, &port); \ tt_int_op(r, OP_GE, -1); \ tt_int_op(r, OP_LE, 0); \ @@ -1162,10 +1123,16 @@ test_addr_ip6_helpers(void *arg) TEST_ADDR_LOOKUP_XFAIL(host_port_str, AF_INET6); \ STMT_END -/** Test tor_addr_parse() and tor_addr_port_parse(). */ static void -test_addr_parse(void *arg) +test_addr_parse_canonical(void *arg) { + int r; + tor_addr_t addr; + uint16_t port; + const char *sv; + uint32_t addr32h; + char buf[TOR_ADDR_BUF_LEN]; + (void)arg; /* Correct calls. */ @@ -1185,6 +1152,22 @@ test_addr_parse(void *arg) TEST_ADDR_V6_PARSE_CANONICAL("::", 0); TEST_ADDR_V6_PARSE_CANONICAL("2::", 0); TEST_ADDR_V6_PARSE_CANONICAL("11:22:33:44:55:66:77:88", 0); + done: + ; +} + +/** Test tor_addr_parse() and tor_addr_port_parse(). */ +static void +test_addr_parse(void *arg) +{ + int r; + tor_addr_t addr; + uint16_t port; + const char *sv; + uint32_t addr32h; + char buf[TOR_ADDR_BUF_LEN]; + + (void)arg; /* IPv6-mapped IPv4 addresses. Tor doesn't really use these. */ TEST_ADDR_V6_PARSE("11:22:33:44:55:66:1.2.3.4", 0, @@ -1669,6 +1652,7 @@ struct testcase_t addr_tests[] = { ADDR_LEGACY(basic), ADDR_LEGACY(ip6_helpers), ADDR_LEGACY(parse), + ADDR_LEGACY(parse_canonical), { "virtaddr", test_virtaddrmap, 0, NULL, NULL }, { "virtaddr_persist", test_virtaddrmap_persist, TT_FORK, NULL, NULL }, { "localname", test_addr_localname, 0, NULL, NULL }, diff --git a/src/test/test_btrack.c b/src/test/test_btrack.c index 21e88a57b6..80da7829ae 100644 --- a/src/test/test_btrack.c +++ b/src/test/test_btrack.c @@ -4,7 +4,7 @@ #include "core/or/or.h" #include "test/test.h" -#include "test_helpers.h" +#include "test/test_helpers.h" #include "test/log_test_helpers.h" #define OCIRC_EVENT_PRIVATE diff --git a/src/test/test_config.c b/src/test/test_config.c index 9b715b2ecf..78f9ae9c3f 100644 --- a/src/test/test_config.c +++ b/src/test/test_config.c @@ -16,7 +16,7 @@ #include "core/or/circuitmux_ewma.h" #include "core/or/circuitbuild.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "test/test.h" diff --git a/src/test/test_confmgr.c b/src/test/test_confmgr.c index 5f73d9754b..d5c73b48e4 100644 --- a/src/test/test_confmgr.c +++ b/src/test/test_confmgr.c @@ -13,7 +13,7 @@ #include "core/or/or.h" #include "lib/encoding/confline.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "test/test.h" #include "test/log_test_helpers.h" diff --git a/src/test/test_confparse.c b/src/test/test_confparse.c index bd2b5cdf1b..d929d1e361 100644 --- a/src/test/test_confparse.c +++ b/src/test/test_confparse.c @@ -14,7 +14,7 @@ #include "core/or/or.h" #include "lib/encoding/confline.h" #include "feature/nodelist/routerset.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "test/test.h" #include "test/log_test_helpers.h" diff --git a/src/test/test_dir.c b/src/test/test_dir.c index 17d6db1e4d..6329ff7750 100644 --- a/src/test/test_dir.c +++ b/src/test/test_dir.c @@ -26,7 +26,7 @@ #include "core/or/or.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "core/mainloop/connection.h" #include "core/or/relay.h" #include "core/or/versions.h" diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c index fc7c5d5800..8f2d507743 100644 --- a/src/test/test_entryconn.c +++ b/src/test/test_entryconn.c @@ -11,7 +11,7 @@ #include "feature/client/addressmap.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "core/mainloop/connection.h" #include "core/or/connection_edge.h" #include "feature/nodelist/nodelist.h" diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c index c8dd4b03ea..d59b1c7153 100644 --- a/src/test/test_entrynodes.c +++ b/src/test/test_entrynodes.c @@ -18,7 +18,7 @@ #include "core/or/circuitlist.h" #include "core/or/circuitbuild.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "lib/crypt_ops/crypto_rand.h" #include "feature/dircommon/directory.h" #include "feature/dirclient/dirclient.h" @@ -1734,7 +1734,8 @@ test_entry_guard_manage_primary(void *arg) dir_info_str =guard_selection_get_err_str_if_dir_info_missing(gs, 1, 2, 3); tt_str_op(dir_info_str, OP_EQ, "We're missing descriptors for 1/2 of our primary entry guards " - "(total microdescriptors: 2/3)."); + "(total microdescriptors: 2/3). That's ok. We will try to fetch " + "missing descriptors soon."); tor_free(dir_info_str); } diff --git a/src/test/test_helpers.c b/src/test/test_helpers.c index 31a6540efc..8eb3c2c928 100644 --- a/src/test/test_helpers.c +++ b/src/test/test_helpers.c @@ -16,7 +16,7 @@ #include "lib/buf/buffers.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "app/main/subsysmgr.h" #include "core/mainloop/connection.h" #include "lib/crypt_ops/crypto_rand.h" diff --git a/src/test/test_options.c b/src/test/test_options.c index a6bccdc524..0747a2e062 100644 --- a/src/test/test_options.c +++ b/src/test/test_options.c @@ -5,7 +5,7 @@ #define CONFIG_PRIVATE #include "core/or/or.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "app/config/config.h" #include "test/test.h" #include "lib/geoip/geoip.h" diff --git a/src/test/test_pt.c b/src/test/test_pt.c index 362c6664db..8f3ce03c42 100644 --- a/src/test/test_pt.c +++ b/src/test/test_pt.c @@ -11,7 +11,7 @@ #define PROCESS_PRIVATE #include "core/or/or.h" #include "app/config/config.h" -#include "app/config/confparse.h" +#include "lib/confmgt/confparse.h" #include "feature/control/control.h" #include "feature/control/control_events.h" #include "feature/client/transports.h" diff --git a/src/trunnel/trunnel-local.h b/src/trunnel/trunnel-local.h index c4118fce4c..80da371560 100644 --- a/src/trunnel/trunnel-local.h +++ b/src/trunnel/trunnel-local.h @@ -14,5 +14,6 @@ #define trunnel_reallocarray tor_reallocarray #define trunnel_assert tor_assert #define trunnel_memwipe(mem, len) memwipe((mem), 0, (len)) +#define trunnel_abort tor_abort_ #endif |