]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
plugins: track all loaded plugins in a list 5317/head
authorJason Ish <jason.ish@oisf.net>
Tue, 11 Aug 2020 16:26:43 +0000 (10:26 -0600)
committerVictor Julien <victor@inliniac.net>
Mon, 24 Aug 2020 07:16:27 +0000 (09:16 +0200)
Track the pointer returned from dlopen in a list to prevent a
resource leak by the pointer going out of scope.

Found by Coverity, CID 1465661.

Redmine issue:
https://redmine.openinfosecfoundation.org/issues/3864

src/util-plugin.c

index 95125ce7162012f3ed896ad5a7cfbac48b87798f..94f7c13d51128216ad382c6cf5ffc5805c656e23 100644 (file)
 
 #include <dlfcn.h>
 
+typedef struct PluginListNode_ {
+    SCPlugin *plugin;
+    void *lib;
+    TAILQ_ENTRY(PluginListNode_) entries;
+} PluginListNode;
+
+/**
+ * The list of loaded plugins.
+ *
+ * Currently only used as a place to stash the pointer returned from
+ * dlopen, but could have other uses, such as a plugin unload destructor.
+ */
+static TAILQ_HEAD(, PluginListNode_) plugins = TAILQ_HEAD_INITIALIZER(plugins);
+
 static TAILQ_HEAD(, SCPluginFileType_) output_types =
     TAILQ_HEAD_INITIALIZER(output_types);
 
@@ -38,11 +52,22 @@ static void InitPlugin(char *path)
         SCPlugin *plugin = dlsym(lib, "PluginSpec");
         if (plugin == NULL) {
             SCLogError(SC_ERR_PLUGIN, "Plugin does not export a plugin specification: %s", path);
+            dlclose(lib);
         } else {
             BUG_ON(plugin->name == NULL);
             BUG_ON(plugin->author == NULL);
             BUG_ON(plugin->license == NULL);
             BUG_ON(plugin->Init == NULL);
+
+            PluginListNode *node = SCCalloc(1, sizeof(*node));
+            if (node == NULL) {
+                SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocated memory for plugin");
+                dlclose(lib);
+                return;
+            }
+            node->plugin = plugin;
+            node->lib = lib;
+            TAILQ_INSERT_TAIL(&plugins, node, entries);
             SCLogNotice("Initializing plugin %s; author=%s; license=%s",
                 plugin->name, plugin->author, plugin->license);
             (*plugin->Init)();