]> granicus.if.org Git - sudo/commitdiff
Plug memory leak when an I/O plugin is specified in sudo.conf
authorTodd C. Miller <Todd.Miller@sudo.ws>
Tue, 17 Apr 2018 19:41:44 +0000 (13:41 -0600)
committerTodd C. Miller <Todd.Miller@sudo.ws>
Tue, 17 Apr 2018 19:41:44 +0000 (13:41 -0600)
but the I/O plugin is not configured.

src/load_plugins.c
src/sudo.c
src/sudo_plugin_int.h

index dc7cbdade203bfa6a77dd915b4224cafdf315aa1..620e72f45f360ae54deefe2de2ade98fff222dbf 100644 (file)
@@ -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;
        }
index b187454881e84f3710803a0e7473f64127d4d3b2..a287ef899ed9e6f5a9795db2ff923a7b9f82a584 100644 (file)
@@ -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;
index 8d7dde0932de0a2893ac2f6c2538ec6e8475929f..c5fce3406d8840bd549aa340a2cbf19c0d7b4a4d 100644 (file)
@@ -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 {