diff options
author | Nick Mathewson <nickm@torproject.org> | 2017-09-06 16:50:05 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-09-11 16:23:16 -0400 |
commit | c4cb969a2a90570120f57f72448241af41e21e97 (patch) | |
tree | d6c90ba52d8b30fc8b6bfb7c36f1bfc0b667b49d /src/or/config.c | |
parent | ab18e5e5fcff7fbdbf0905e6dd2585b7e4a10108 (diff) | |
download | tor-c4cb969a2a90570120f57f72448241af41e21e97.tar.gz tor-c4cb969a2a90570120f57f72448241af41e21e97.zip |
Taboo the get_options() function while options are validating
When option validation or transition is happening, there are no
"current options" -- only "old options" and "maybe new options".
Looking at get_options() is likely a mistake, so have a nonfatal
assertion let us know if we do that.
Closes 22281.
Diffstat (limited to 'src/or/config.c')
-rw-r--r-- | src/or/config.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/src/or/config.c b/src/or/config.c index eb89d6f5ee..2c507ab9d9 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -766,6 +766,9 @@ static int have_parsed_cmdline = 0; static char *global_dirfrontpagecontents = NULL; /** List of port_cfg_t for all configured ports. */ static smartlist_t *configured_ports = NULL; +/** True iff we're currently validating options, and any calls to + * get_options() are likely to be bugs. */ +static int in_option_validation = 0; /** Return the contents of our frontpage string, or NULL if not configured. */ MOCK_IMPL(const char*, @@ -779,6 +782,7 @@ MOCK_IMPL(or_options_t *, get_options_mutable, (void)) { tor_assert(global_options); + tor_assert_nonfatal(! in_option_validation); return global_options; } @@ -2304,24 +2308,35 @@ options_trial_assign(config_line_t *list, unsigned flags, char **msg) return r; } + setopt_err_t rv; + + in_option_validation = 1; + if (options_validate(get_options_mutable(), trial_options, global_default_options, 1, msg) < 0) { or_options_free(trial_options); - return SETOPT_ERR_PARSE; /*XXX make this a separate return value. */ + rv = SETOPT_ERR_PARSE; /*XXX make this a separate return value. */ + goto done; } if (options_transition_allowed(get_options(), trial_options, msg) < 0) { or_options_free(trial_options); - return SETOPT_ERR_TRANSITION; + rv = SETOPT_ERR_TRANSITION; + goto done; } + in_option_validation = 0; if (set_options(trial_options, msg)<0) { or_options_free(trial_options); - return SETOPT_ERR_SETTING; + rv = SETOPT_ERR_SETTING; + goto done; } /* we liked it. put it in place. */ - return SETOPT_OK; + rv = SETOPT_OK; + done: + in_option_validation = 0; + return rv; } /** Print a usage message for tor. */ @@ -2824,8 +2839,11 @@ static int options_validate_cb(void *old_options, void *options, void *default_options, int from_setconf, char **msg) { - return options_validate(old_options, options, default_options, + in_option_validation = 1; + int rv = options_validate(old_options, options, default_options, from_setconf, msg); + in_option_validation = 0; + return rv; } #define REJECT(arg) \ @@ -5200,6 +5218,7 @@ options_init_from_string(const char *cf_defaults, const char *cf, } newoptions->IncludeUsed = cf_has_include; + in_option_validation = 1; /* Validate newoptions */ if (options_validate(oldoptions, newoptions, newdefaultoptions, @@ -5212,17 +5231,20 @@ options_init_from_string(const char *cf_defaults, const char *cf, err = SETOPT_ERR_TRANSITION; goto err; } + in_option_validation = 0; if (set_options(newoptions, msg)) { err = SETOPT_ERR_SETTING; goto err; /* frees and replaces old options */ } + or_options_free(global_default_options); global_default_options = newdefaultoptions; return SETOPT_OK; err: + in_option_validation = 0; or_options_free(newoptions); or_options_free(newdefaultoptions); if (*msg) { |