From 2777003e121a5d764b54c62590e7ceb46ae2c157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Valverde?= Date: Fri, 29 Sep 2017 19:49:51 +0100 Subject: Add version check for plugin compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only plugins built for the same feature release (X.Y) are assured binary compatibility. Make sure we don't try to run unsuitable code and, if so, warn the user. This might happen for example if the user manually copies a binary plugin to the wrong folder, intentionally or by accident. I'm using "release version" to loosely mean not a patch release (i.e: a feature release). Change-Id: I896e9cbbd2d3843623fff6af8ef51002ec06f1f8 Reviewed-on: https://code.wireshark.org/review/23807 Petri-Dish: João Valverde Tested-by: Petri Dish Buildbot Reviewed-by: João Valverde --- CMakeLists.txt | 5 +++-- cmakeconfig.h.in | 1 + configure.ac | 6 +++++- doc/plugins.example/Makefile.am | 6 +++++- doc/plugins.example/hello.c | 5 +++-- plugins/stats_tree/stats_tree_plugin.c | 3 ++- tools/make-dissector-reg.py | 4 ++-- wsutil/filesystem.c | 6 ++---- wsutil/plugins.c | 21 ++++++++++++++++++--- 9 files changed, 41 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d34f81586..b0370a9a33 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ set(PROJECT_MINOR_VERSION 5) set(PROJECT_PATCH_VERSION 0) set(PROJECT_BUILD_VERSION ${GIT_REVISION}) set(PROJECT_VERSION_EXTENSION "") +set(PROJECT_RELEASE_VERSION "${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}") if(DEFINED ENV{WIRESHARK_VERSION_EXTRA}) set(PROJECT_VERSION_EXTENSION "$ENV{WIRESHARK_VERSION_EXTRA}") @@ -1360,7 +1361,7 @@ if(LIBSSH_FOUND) endif() # Directory where plugins and Lua dissectors can be found. -set(PLUGIN_VERSION_DIR "plugins/${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}") +set(PLUGIN_VERSION_DIR "plugins/${PROJECT_RELEASE_VERSION}") set(PLUGIN_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/${CPACK_PACKAGE_NAME}/${PLUGIN_VERSION_DIR}") # Used by the WiresharkConfig.cmake.in module if (WIN32) @@ -1410,7 +1411,7 @@ else() endif() if(ENABLE_APPLICATION_BUNDLE) - set(_plugin_dir "${CMAKE_BINARY_DIR}/run/Wireshark.app/Contents/PlugIns/wireshark/${PROJECT_MAJOR_VERSION}.${PROJECT_MINOR_VERSION}") + set(_plugin_dir "${CMAKE_BINARY_DIR}/run/Wireshark.app/Contents/PlugIns/wireshark/${PROJECT_RELEASE_VERSION}") else() get_target_property(_libwireshark_location epan LOCATION) get_filename_component(_plugin_dir "${_libwireshark_location}" PATH) diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in index 628ea2c067..66d6c25d37 100644 --- a/cmakeconfig.h.in +++ b/cmakeconfig.h.in @@ -13,6 +13,7 @@ #define VERSION_MINOR ${PROJECT_MINOR_VERSION} #define VERSION_MICRO ${PROJECT_PATCH_VERSION} +#define VERSION_RELEASE "${PROJECT_RELEASE_VERSION}" #define VERSION_FLAVOR "${VERSION_FLAVOR}" /* FIXME: Move the path stuff to the CMakeInstallDirs.cmake file */ diff --git a/configure.ac b/configure.ac index f71c7c7ed6..78f9375423 100644 --- a/configure.ac +++ b/configure.ac @@ -16,6 +16,10 @@ AC_INIT(Wireshark, [version_major.version_minor.version_micro_extra], http://bug CONFIG_ARGS="$*" AC_SUBST(CONFIG_ARGS) +VERSION_RELEASE="version_major.version_minor" +AC_SUBST(VERSION_RELEASE) +AC_DEFINE_UNQUOTED([VERSION_RELEASE], ["$VERSION_RELEASE"], [Wireshark feature release version (X.Y)]) + # Minimum autoconf version we require. AC_PREREQ(2.64) # Variable expansion doesn't work in AC_PREREQ() @@ -2596,7 +2600,7 @@ dnl check whether plugins should be enabled and, if they should be, dnl check for plugins directory - stolen from Amanda's configure.ac dnl dnl we don't wish to expand ${libdir} yet -plugindir="\${libdir}/wireshark/plugins/version_major.version_minor" +plugindir="\${libdir}/wireshark/plugins/$VERSION_RELEASE" AC_ARG_WITH(plugins, AC_HELP_STRING( [--with-plugins@<:@=DIR@:>@], [support plugins (installed in DIR, if supplied) @<:@default=yes, if possible@:>@]), diff --git a/doc/plugins.example/Makefile.am b/doc/plugins.example/Makefile.am index 1b9b5b0d27..b477e13933 100644 --- a/doc/plugins.example/Makefile.am +++ b/doc/plugins.example/Makefile.am @@ -23,17 +23,21 @@ WARNFLAGS = -Wall -Wextra plugindir := $(shell PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) $(PKG_CONFIG) --define-variable=libdir=$(libdir) --variable plugindir wireshark) +release_version := $(notdir $(plugindir)) + plugin_LTLIBRARIES = hello.la hello_la_SOURCES = hello.c +hello_la_CPPFLAGS = -DVERSION_RELEASE=\"$(release_version)\" + hello_la_CFLAGS = $(WIRESHARK_CFLAGS) -fvisibility=hidden $(WARNFLAGS) hello_la_LDFLAGS = -module -avoid-version -shared hello_la_LIBADD = $(WIRESHARK_LIBS) -homedir = $${HOME}/.local/lib/wireshark/plugins/$(notdir $(plugindir)) +homedir = $${HOME}/.local/lib/wireshark/plugins/$(release_version) install-home: $(MKDIR_P) $(homedir) || exit 1; \ diff --git a/doc/plugins.example/hello.c b/doc/plugins.example/hello.c index af78239e3a..8493d12ad0 100644 --- a/doc/plugins.example/hello.c +++ b/doc/plugins.example/hello.c @@ -32,7 +32,8 @@ #define DLL_PUBLIC __attribute__((__visibility__("default"))) -DLL_PUBLIC const gchar version[] = VERSION; +DLL_PUBLIC const gchar plugin_version[] = VERSION; +DLL_PUBLIC const gchar plugin_release[] = VERSION_RELEASE; DLL_PUBLIC void plugin_register(void); @@ -45,7 +46,7 @@ static dissector_handle_t handle_hello; static int dissect_hello(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_) { - proto_tree_add_protocol_format(tree, proto_hello, tvb, 0, -1, "This is Hello version %s, a Wireshark postdissector plugin prototype", version); + proto_tree_add_protocol_format(tree, proto_hello, tvb, 0, -1, "This is Hello version %s, a Wireshark postdissector plugin prototype", plugin_version); return tvb_captured_length(tvb); } diff --git a/plugins/stats_tree/stats_tree_plugin.c b/plugins/stats_tree/stats_tree_plugin.c index 2c91d62e86..da08bba51e 100644 --- a/plugins/stats_tree/stats_tree_plugin.c +++ b/plugins/stats_tree/stats_tree_plugin.c @@ -34,7 +34,8 @@ #include "pinfo_stats_tree.h" -WS_DLL_PUBLIC_DEF const gchar version[] = "0.0.1"; +WS_DLL_PUBLIC_DEF const gchar plugin_version[] = "0.0.1"; +WS_DLL_PUBLIC_DEF const gchar plugin_release[] = VERSION_RELEASE; WS_DLL_PUBLIC_DEF void plugin_register_tap_listener(void) { diff --git a/tools/make-dissector-reg.py b/tools/make-dissector-reg.py index 7eb035489f..5d59f886bb 100755 --- a/tools/make-dissector-reg.py +++ b/tools/make-dissector-reg.py @@ -202,8 +202,8 @@ if registertype == "plugin" or registertype == "plugin_wtap": #include "ws_symbol_export.h" #ifndef ENABLE_STATIC -WS_DLL_PUBLIC_DEF void plugin_register (void); -WS_DLL_PUBLIC_DEF const gchar version[] = VERSION; +WS_DLL_PUBLIC_DEF const gchar plugin_version[] = VERSION; +WS_DLL_PUBLIC_DEF const gchar plugin_release[] = VERSION_RELEASE; """ else: diff --git a/wsutil/filesystem.c b/wsutil/filesystem.c index ce1eca773b..8f0a3ead2d 100644 --- a/wsutil/filesystem.c +++ b/wsutil/filesystem.c @@ -1066,8 +1066,7 @@ get_plugins_dir_with_version(void) if (!plugin_dir) init_plugin_dir(); if (plugin_dir && !plugin_dir_with_version) - plugin_dir_with_version = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%d.%d", - plugin_dir, VERSION_MAJOR, VERSION_MINOR); + plugin_dir_with_version = g_build_filename(plugin_dir, VERSION_RELEASE, (gchar *)NULL); return plugin_dir_with_version; } @@ -1086,8 +1085,7 @@ get_plugins_pers_dir_with_version(void) if (!plugin_pers_dir) init_plugin_pers_dir(); if (plugin_pers_dir && !plugin_pers_dir_with_version) - plugin_pers_dir_with_version = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%d.%d", - plugin_pers_dir, VERSION_MAJOR, VERSION_MINOR); + plugin_pers_dir_with_version = g_build_filename(plugin_pers_dir, VERSION_RELEASE, (gchar *)NULL); return plugin_pers_dir_with_version; } diff --git a/wsutil/plugins.c b/wsutil/plugins.c index 62ddf997fd..cde504a24e 100644 --- a/wsutil/plugins.c +++ b/wsutil/plugins.c @@ -115,6 +115,7 @@ plugins_scan_dir(const char *dirname, plugin_load_failure_mode mode) gchar *filename; /* current file name */ GModule *handle; /* handle returned by g_module_open */ gpointer symbol; + const char *plug_version, *plug_release; plugin *new_plug; gchar *dot; @@ -182,9 +183,23 @@ plugins_scan_dir(const char *dirname, plugin_load_failure_mode mode) continue; } - if (!g_module_symbol(handle, "version", &symbol)) + if (!g_module_symbol(handle, "plugin_version", &symbol)) { - report_failure("The plugin '%s' has no \"version\" symbol", name); + report_failure("The plugin '%s' has no \"plugin_version\" symbol", name); + g_module_close(handle); + continue; + } + plug_version = (const char *)symbol; + + if (!g_module_symbol(handle, "plugin_release", &symbol)) + { + report_failure("The plugin '%s' has no \"plugin_release\" symbol", name); + g_module_close(handle); + continue; + } + plug_release = (const char *)symbol; + if (strcmp(plug_release, VERSION_RELEASE) != 0) { + report_failure("The plugin '%s' was compiled for Wireshark version %s", name, plug_release); g_module_close(handle); continue; } @@ -192,7 +207,7 @@ plugins_scan_dir(const char *dirname, plugin_load_failure_mode mode) new_plug = (plugin *)g_malloc(sizeof(plugin)); new_plug->handle = handle; new_plug->name = g_strdup(name); - new_plug->version = (char *)symbol; + new_plug->version = plug_version; new_plug->types = g_string_new(NULL); /* -- cgit v1.2.3