From dd2c1c7620951812681a5e0219749715d0f1738c Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 11 Aug 2025 16:28:46 +0200 Subject: [PATCH] plugin-loader: Check version of loaded plugins This prevents loading plugins from older builds that can cause all sorts of issues as they might access struct members in different locations. We don't check the version for statically linked plugins. --- src/libstrongswan/plugins/plugin_loader.c | 41 +++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index 0d4659f127..65e73e468a 100644 --- a/src/libstrongswan/plugins/plugin_loader.c +++ b/src/libstrongswan/plugins/plugin_loader.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2014 Tobias Brunner + * Copyright (C) 2010-2025 Tobias Brunner * Copyright (C) 2007 Martin Willi * * Copyright (C) secunet Security Networks AG @@ -46,7 +46,6 @@ typedef struct plugin_entry_t plugin_entry_t; * Statically registered constructors */ static hashtable_t *plugin_constructors = NULL; - #elif !defined(HAVE_DLADDR) #error Neither dynamic linking nor static plugin constructors are supported! #endif @@ -413,6 +412,39 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle, return SUCCESS; } +#ifdef HAVE_DLADDR +/** + * Verify that the plugin version matches that of the daemon + */ +static bool verify_plugin_version(void *handle, char *name) +{ + char field[128]; + char **version; + + if (snprintf(field, sizeof(field), "%s_plugin_version", + name) >= sizeof(field)) + { + return FALSE; + } + translate(field, "-", "_"); + + version = dlsym(handle, field); + if (!version) + { + DBG1(DBG_LIB, "plugin '%s': failed to load - version field %s missing", + name, field); + return FALSE; + } + if (strcmp(*version, VERSION)) + { + DBG1(DBG_LIB, "plugin '%s': failed to load - plugin version %s doesn't " + "match version %s", name, *version, VERSION); + return FALSE; + } + return TRUE; +} +#endif /* HAVE_DLADDR */ + /** * load a single plugin */ @@ -479,6 +511,11 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name, DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror()); return NULL; } + if (!verify_plugin_version(handle, name)) + { + dlclose(handle); + return NULL; + } switch (create_plugin(this, handle, name, create, TRUE, critical, &entry)) { case SUCCESS: -- 2.47.2