mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
Fix a memory leak in --dump-config
When freeing a configuration object from confparse.c in dump_config(), we need to call the appropriate higher-level free function (like or_options_free()) and not just config_free(). This only happens with options (since they're the one where options_validate allocates extra stuff) and only when running --dump-config with something other than minimal (since OPTIONS_DUMP_MINIMAL doesn't hit this code). Fixes bug 27893; bugfix on 0.3.2.1-alpha.
This commit is contained in:
parent
de0b07c634
commit
8812f562a0
3
changes/bug27893
Normal file
3
changes/bug27893
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
o Minor bugfixes (memory leaks):
|
||||||
|
- Fix a small memory leak when calling Tor with --dump-config.
|
||||||
|
Fixes bug 27893; bugfix on 0.3.2.1-alpha.
|
@ -824,6 +824,7 @@ static void config_maybe_load_geoip_files_(const or_options_t *options,
|
|||||||
static int options_validate_cb(void *old_options, void *options,
|
static int options_validate_cb(void *old_options, void *options,
|
||||||
void *default_options,
|
void *default_options,
|
||||||
int from_setconf, char **msg);
|
int from_setconf, char **msg);
|
||||||
|
static void options_free_cb(void *options);
|
||||||
static void cleanup_protocol_warning_severity_level(void);
|
static void cleanup_protocol_warning_severity_level(void);
|
||||||
static void set_protocol_warning_severity_level(int warning_severity);
|
static void set_protocol_warning_severity_level(int warning_severity);
|
||||||
|
|
||||||
@ -839,6 +840,7 @@ STATIC config_format_t options_format = {
|
|||||||
option_deprecation_notes_,
|
option_deprecation_notes_,
|
||||||
option_vars_,
|
option_vars_,
|
||||||
options_validate_cb,
|
options_validate_cb,
|
||||||
|
options_free_cb,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3149,6 +3151,13 @@ options_validate_cb(void *old_options, void *options, void *default_options,
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Callback to free an or_options_t */
|
||||||
|
static void
|
||||||
|
options_free_cb(void *options)
|
||||||
|
{
|
||||||
|
or_options_free_(options);
|
||||||
|
}
|
||||||
|
|
||||||
#define REJECT(arg) \
|
#define REJECT(arg) \
|
||||||
STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
|
STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
|
||||||
#if defined(__GNUC__) && __GNUC__ <= 3
|
#if defined(__GNUC__) && __GNUC__ <= 3
|
||||||
|
@ -1009,8 +1009,9 @@ config_dump(const config_format_t *fmt, const void *default_options,
|
|||||||
result = smartlist_join_strings(elements, "", 0, NULL);
|
result = smartlist_join_strings(elements, "", 0, NULL);
|
||||||
SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
|
SMARTLIST_FOREACH(elements, char *, cp, tor_free(cp));
|
||||||
smartlist_free(elements);
|
smartlist_free(elements);
|
||||||
if (defaults_tmp)
|
if (defaults_tmp) {
|
||||||
config_free(fmt, defaults_tmp);
|
fmt->free_fn(defaults_tmp);
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +155,9 @@ typedef struct config_var_t {
|
|||||||
* of arguments. */
|
* of arguments. */
|
||||||
typedef int (*validate_fn_t)(void*,void*,void*,int,char**);
|
typedef int (*validate_fn_t)(void*,void*,void*,int,char**);
|
||||||
|
|
||||||
|
/** Callback to free a configuration object. */
|
||||||
|
typedef void (*free_cfg_fn_t)(void*);
|
||||||
|
|
||||||
/** Information on the keys, value types, key-to-struct-member mappings,
|
/** Information on the keys, value types, key-to-struct-member mappings,
|
||||||
* variable descriptions, validation functions, and abbreviations for a
|
* variable descriptions, validation functions, and abbreviations for a
|
||||||
* configuration or storage format. */
|
* configuration or storage format. */
|
||||||
@ -169,6 +172,7 @@ typedef struct config_format_t {
|
|||||||
config_var_t *vars; /**< List of variables we recognize, their default
|
config_var_t *vars; /**< List of variables we recognize, their default
|
||||||
* values, and where we stick them in the structure. */
|
* values, and where we stick them in the structure. */
|
||||||
validate_fn_t validate_fn; /**< Function to validate config. */
|
validate_fn_t validate_fn; /**< Function to validate config. */
|
||||||
|
free_cfg_fn_t free_fn; /**< Function to free the configuration. */
|
||||||
/** If present, extra is a LINELIST variable for unrecognized
|
/** If present, extra is a LINELIST variable for unrecognized
|
||||||
* lines. Otherwise, unrecognized lines are an error. */
|
* lines. Otherwise, unrecognized lines are an error. */
|
||||||
config_var_t *extra;
|
config_var_t *extra;
|
||||||
|
@ -143,6 +143,8 @@ static int or_state_validate_cb(void *old_options, void *options,
|
|||||||
void *default_options,
|
void *default_options,
|
||||||
int from_setconf, char **msg);
|
int from_setconf, char **msg);
|
||||||
|
|
||||||
|
static void or_state_free_cb(void *state);
|
||||||
|
|
||||||
/** Magic value for or_state_t. */
|
/** Magic value for or_state_t. */
|
||||||
#define OR_STATE_MAGIC 0x57A73f57
|
#define OR_STATE_MAGIC 0x57A73f57
|
||||||
|
|
||||||
@ -162,6 +164,7 @@ static const config_format_t state_format = {
|
|||||||
NULL,
|
NULL,
|
||||||
state_vars_,
|
state_vars_,
|
||||||
or_state_validate_cb,
|
or_state_validate_cb,
|
||||||
|
or_state_free_cb,
|
||||||
&state_extra_var,
|
&state_extra_var,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -259,6 +262,12 @@ or_state_validate_cb(void *old_state, void *state, void *default_state,
|
|||||||
return or_state_validate(state, msg);
|
return or_state_validate(state, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
or_state_free_cb(void *state)
|
||||||
|
{
|
||||||
|
or_state_free_(state);
|
||||||
|
}
|
||||||
|
|
||||||
/** Return 0 if every setting in <b>state</b> is reasonable, and a
|
/** Return 0 if every setting in <b>state</b> is reasonable, and a
|
||||||
* permissible transition from <b>old_state</b>. Else warn and return -1.
|
* permissible transition from <b>old_state</b>. Else warn and return -1.
|
||||||
* Should have no side effects, except for normalizing the contents of
|
* Should have no side effects, except for normalizing the contents of
|
||||||
|
@ -63,6 +63,7 @@ DUMMY_TYPECHECK_INSTANCE(sr_disk_state_t);
|
|||||||
static int
|
static int
|
||||||
disk_state_validate_cb(void *old_state, void *state, void *default_state,
|
disk_state_validate_cb(void *old_state, void *state, void *default_state,
|
||||||
int from_setconf, char **msg);
|
int from_setconf, char **msg);
|
||||||
|
static void disk_state_free_cb(void *);
|
||||||
|
|
||||||
/* Array of variables that are saved to disk as a persistent state. */
|
/* Array of variables that are saved to disk as a persistent state. */
|
||||||
static config_var_t state_vars[] = {
|
static config_var_t state_vars[] = {
|
||||||
@ -96,6 +97,7 @@ static const config_format_t state_format = {
|
|||||||
NULL,
|
NULL,
|
||||||
state_vars,
|
state_vars,
|
||||||
disk_state_validate_cb,
|
disk_state_validate_cb,
|
||||||
|
disk_state_free_cb,
|
||||||
&state_extra_var,
|
&state_extra_var,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -342,6 +344,12 @@ disk_state_validate_cb(void *old_state, void *state, void *default_state,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
disk_state_free_cb(void *state)
|
||||||
|
{
|
||||||
|
disk_state_free_(state);
|
||||||
|
}
|
||||||
|
|
||||||
/* Parse the Commit line(s) in the disk state and translate them to the
|
/* Parse the Commit line(s) in the disk state and translate them to the
|
||||||
* the memory state. Return 0 on success else -1 on error. */
|
* the memory state. Return 0 on success else -1 on error. */
|
||||||
static int
|
static int
|
||||||
|
Loading…
Reference in New Issue
Block a user