diff --git a/src/libstrongswan/plugins/plugin_loader.c b/src/libstrongswan/plugins/plugin_loader.c index 0d4659f12..65e73e468 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: