From: Todd C. Miller Date: Tue, 17 Apr 2018 19:41:44 +0000 (-0600) Subject: Plug memory leak when an I/O plugin is specified in sudo.conf X-Git-Tag: SUDO_1_8_23^2~24 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=18e06825fb26d6527d5168f750f8e0db398cd84c;p=sudo Plug memory leak when an I/O plugin is specified in sudo.conf but the I/O plugin is not configured. --- diff --git a/src/load_plugins.c b/src/load_plugins.c index dc7cbdade..620e72f45 100644 --- a/src/load_plugins.c +++ b/src/load_plugins.c @@ -264,8 +264,13 @@ static void free_plugin_info(struct plugin_info *info) { free(info->path); - free(info->options); free(info->symbol_name); + if (info->options != NULL) { + int i = 0; + while (info->options[i] != NULL) + free(info->options[i++]); + free(info->options); + } free(info); } @@ -294,7 +299,7 @@ sudo_load_plugins(struct plugin_container *policy_plugin, /* * If no policy plugin, fall back to the default (sudoers). - * If there is also no I/O log plugin, sudoers for that too. + * If there is also no I/O log plugin, use sudoers for that too. */ if (policy_plugin->handle == NULL) { /* Default policy plugin */ @@ -303,11 +308,15 @@ sudo_load_plugins(struct plugin_container *policy_plugin, sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); goto done; } - info->symbol_name = "sudoers_policy"; - info->path = SUDOERS_PLUGIN; + info->symbol_name = strdup("sudoers_policy"); + info->path = strdup(SUDOERS_PLUGIN); + if (info->symbol_name == NULL || info->path == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + goto done; + } /* info->options = NULL; */ ret = sudo_load_plugin(policy_plugin, io_plugins, info); - free(info); + free_plugin_info(info); if (!ret) goto done; @@ -318,11 +327,15 @@ sudo_load_plugins(struct plugin_container *policy_plugin, sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); goto done; } - info->symbol_name = "sudoers_io"; - info->path = SUDOERS_PLUGIN; + info->symbol_name = strdup("sudoers_io"); + info->path = strdup(SUDOERS_PLUGIN); + if (info->symbol_name == NULL || info->path == NULL) { + sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); + goto done; + } /* info->options = NULL; */ ret = sudo_load_plugin(policy_plugin, io_plugins, info); - free(info); + free_plugin_info(info); if (!ret) goto done; } diff --git a/src/sudo.c b/src/sudo.c index b18745488..a287ef899 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -124,6 +124,7 @@ static void iolog_close(struct plugin_container *plugin, int exit_status, int error); static int iolog_show_version(struct plugin_container *plugin, int verbose); static void iolog_unlink(struct plugin_container *plugin); +static void free_plugin_container(struct plugin_container *plugin, bool ioplugin); __dso_public int main(int argc, char *argv[], char *envp[]); @@ -1359,8 +1360,26 @@ iolog_unlink(struct plugin_container *plugin) } /* Remove from io_plugins list and free. */ TAILQ_REMOVE(&io_plugins, plugin, entries); + free_plugin_container(plugin, true); + + debug_return; +} + +static void +free_plugin_container(struct plugin_container *plugin, bool ioplugin) +{ + debug_decl(free_plugin_container, SUDO_DEBUG_PLUGIN) + free(plugin->path); - free(plugin); + free(plugin->name); + if (plugin->options != NULL) { + int i = 0; + while (plugin->options[i] != NULL) + free(plugin->options[i++]); + free(plugin->options); + } + if (ioplugin) + free(plugin); debug_return; } @@ -1429,11 +1448,10 @@ gc_run(void) } /* Free plugin structs. */ - free(policy_plugin.path); + free_plugin_container(&policy_plugin, false); while ((plugin = TAILQ_FIRST(&io_plugins))) { TAILQ_REMOVE(&io_plugins, plugin, entries); - free(plugin->path); - free(plugin); + free_plugin_container(plugin, true); } debug_return; diff --git a/src/sudo_plugin_int.h b/src/sudo_plugin_int.h index 8d7dde093..c5fce3406 100644 --- a/src/sudo_plugin_int.h +++ b/src/sudo_plugin_int.h @@ -86,9 +86,9 @@ struct io_plugin_1_1 { struct plugin_container { TAILQ_ENTRY(plugin_container) entries; struct sudo_conf_debug_file_list *debug_files; - const char *name; + char *name; char *path; - char * const *options; + char **options; void *handle; int debug_instance; union {