Add version check for plugin compatibility

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 <j@v6e.pt>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: João Valverde <j@v6e.pt>
This commit is contained in:
João Valverde 2017-09-29 19:49:51 +01:00 committed by João Valverde
parent d477ea35a9
commit 2777003e12
9 changed files with 41 additions and 16 deletions

View File

@ -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)

View File

@ -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 */

View File

@ -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@:>@]),

View File

@ -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; \

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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:

View File

@ -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;
}

View File

@ -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);
/*