From: Tobias Brunner Date: Mon, 11 Aug 2025 14:28:46 +0000 (+0200) Subject: plugin-loader: Check version of loaded plugins X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2F2835-plugin-versions;p=thirdparty%2Fstrongswan.git 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. --- 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: