diff options
author | David Goulet <dgoulet@torproject.org> | 2023-10-18 14:40:18 +0000 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2023-10-18 14:40:18 +0000 |
commit | cc31724f409ee5cff10d82ca05d43e04a85a44e1 (patch) | |
tree | 98b93752cd9545cfccab9f5c7197f99a977065ab /src/core | |
parent | 2a1fc47d8683fa77ec899255c300e76ebdd8d702 (diff) | |
parent | a382337be629ff74e621d2e24c8048e9e8d31d26 (diff) | |
download | tor-cc31724f409ee5cff10d82ca05d43e04a85a44e1.tar.gz tor-cc31724f409ee5cff10d82ca05d43e04a85a44e1.zip |
Merge branch 'ticket40870_048_02' into 'main'
conflux: Flag set as in full teardown in the free path
Closes #40870
See merge request tpo/core/tor!777
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/or/conflux_pool.c | 43 | ||||
-rw-r--r-- | src/core/or/conflux_pool.h | 2 |
2 files changed, 42 insertions, 3 deletions
diff --git a/src/core/or/conflux_pool.c b/src/core/or/conflux_pool.c index 4a7e941372..ec2938aefc 100644 --- a/src/core/or/conflux_pool.c +++ b/src/core/or/conflux_pool.c @@ -1607,7 +1607,22 @@ linked_circuit_free(circuit_t *circ, bool is_client) /* Circuit can be freed without being closed and so we try to delete this leg * so we can learn if this circuit is the last leg or not. */ - cfx_del_leg(circ->conflux, circ); + if (cfx_del_leg(circ->conflux, circ)) { + /* Check for instances of bug #40870, which we suspect happen + * during exit. If any happen outside of exit, BUG and warn. */ + if (!circ->conflux->in_full_teardown) { + /* We should bug and warn if we're not in a shutdown process; that + * means we got here somehow without a close. */ + if (BUG(!shutting_down)) { + log_warn(LD_BUG, + "Conflux circuit %p being freed without being marked for " + "full teardown via close, with shutdown state %d. " + "Please report this.", circ, shutting_down); + conflux_log_set(LOG_WARN, circ->conflux, is_client); + } + circ->conflux->in_full_teardown = true; + } + } if (CONFLUX_NUM_LEGS(circ->conflux) > 0) { /* The last leg will free the streams but until then, we nullify to avoid @@ -2126,14 +2141,36 @@ conflux_log_set(int loglevel, const conflux_t *cfx, bool is_client) } } +/** + * Conflux needs a notification when tor_shutdown() begins, so that + * when circuits are freed, new legs are not launched. + * + * This needs a separate notification from conflux_pool_free_all(), + * because circuits must be freed before that function. + */ +void +conflux_notify_shutdown(void) +{ + shutting_down = true; +} + +#ifdef TOR_UNIT_TESTS +/** + * For unit tests: Clear the shutting down state so we resume building legs. + */ +void +conflux_clear_shutdown(void) +{ + shutting_down = false; +} +#endif + /** Free and clean up the conflux pool subsystem. This is called by the subsys * manager AFTER all circuits have been freed which implies that all objects in * the pools aren't referenced anymore. */ void conflux_pool_free_all(void) { - shutting_down = true; - digest256map_free(client_linked_pool, free_conflux_void_); digest256map_free(server_linked_pool, free_conflux_void_); digest256map_free(client_unlinked_pool, free_unlinked_void_); diff --git a/src/core/or/conflux_pool.h b/src/core/or/conflux_pool.h index afa4d9d058..eba726b03a 100644 --- a/src/core/or/conflux_pool.h +++ b/src/core/or/conflux_pool.h @@ -12,6 +12,7 @@ #include "core/or/or.h" void conflux_pool_init(void); +void conflux_notify_shutdown(void); void conflux_pool_free_all(void); origin_circuit_t *conflux_get_circ_for_conn(const entry_connection_t *conn, @@ -41,6 +42,7 @@ void conflux_log_set(int loglevel, const conflux_t *cfx, bool is_client); #ifdef TOR_UNIT_TESTS bool launch_new_set(int num_legs); +void conflux_clear_shutdown(void); digest256map_t *get_linked_pool(bool is_client); digest256map_t *get_unlinked_pool(bool is_client); extern uint8_t DEFAULT_CLIENT_UX; |