diff options
author | teor <teor@torproject.org> | 2019-11-05 14:23:56 +1000 |
---|---|---|
committer | teor <teor@torproject.org> | 2019-11-05 14:23:56 +1000 |
commit | b9269d6d0a19c998295a2b7910b54bf5f4b1e9c6 (patch) | |
tree | 7cc071cec2c75b04b3faec84494d56949912fa75 /src/lib | |
parent | 61694695469824f5daf5155d5f072dd97be22c32 (diff) | |
parent | b985cf2403c109f728abd0d8d3cb231dc5c9893d (diff) | |
download | tor-b9269d6d0a19c998295a2b7910b54bf5f4b1e9c6.tar.gz tor-b9269d6d0a19c998295a2b7910b54bf5f4b1e9c6.zip |
Merge remote-tracking branch 'tor-github/pr/1486'
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/conf/conftypes.h | 5 | ||||
-rw-r--r-- | src/lib/confmgt/confmgt.c | 45 |
2 files changed, 48 insertions, 2 deletions
diff --git a/src/lib/conf/conftypes.h b/src/lib/conf/conftypes.h index 69a5f79bf3..d4e2ea218a 100644 --- a/src/lib/conf/conftypes.h +++ b/src/lib/conf/conftypes.h @@ -178,6 +178,11 @@ typedef struct struct_magic_decl_t { * however, setting them appends to their old value. */ #define CFLG_NOREPLACE (1u<<5) +/** + * Flag to indicate that an option or type cannot be changed while Tor is + * running. + **/ +#define CFLG_IMMUTABLE (1u<<6) /** * A group of flags that should be set on all obsolete options and types. diff --git a/src/lib/confmgt/confmgt.c b/src/lib/confmgt/confmgt.c index 3fdb630e8a..9377736110 100644 --- a/src/lib/confmgt/confmgt.c +++ b/src/lib/confmgt/confmgt.c @@ -1154,6 +1154,41 @@ config_init(const config_mgr_t *mgr, void *options) } /** + * Helper for config_validate_single: see whether any immutable option + * has changed between old_options and new_options. + * + * On success return 0; on failure set *msg_out to a newly allocated + * string explaining what is wrong, and return -1. + */ +static int +config_check_immutable_flags(const config_format_t *fmt, + const void *old_options, + const void *new_options, + char **msg_out) +{ + tor_assert(fmt); + tor_assert(new_options); + if (BUG(! old_options)) + return 0; + + unsigned i; + for (i = 0; fmt->vars[i].member.name; ++i) { + const config_var_t *v = &fmt->vars[i]; + if (! config_var_has_flag(v, CFLG_IMMUTABLE)) + continue; + + if (! struct_var_eq(old_options, new_options, &v->member)) { + tor_asprintf(msg_out, + "While Tor is running, changing %s is not allowed", + v->member.name); + return -1; + } + } + + return 0; +} + +/** * Normalize and validate a single object `options` within a configuration * suite, according to its format. `options` may be modified as appropriate * in order to set ancillary data. If `old_options` is provided, make sure @@ -1189,10 +1224,16 @@ config_validate_single(const config_format_t *fmt, } } - if (fmt->check_transition_fn && old_options) { - if (fmt->check_transition_fn(old_options, options, msg_out) < 0) { + if (old_options) { + if (config_check_immutable_flags(fmt, old_options, options, msg_out) < 0) { return VSTAT_TRANSITION_ERR; } + + if (fmt->check_transition_fn) { + if (fmt->check_transition_fn(old_options, options, msg_out) < 0) { + return VSTAT_TRANSITION_ERR; + } + } } if (fmt->post_normalize_fn) { |