From e43ca00d5255d81d2004bf33f30dab3843e8aa1d Mon Sep 17 00:00:00 2001 From: Tanu Kaskinen Date: Tue, 11 Feb 2020 09:40:49 +0200 Subject: module: Check version before loading a module Since there's no stable API for modules, all modules need to be compiled together with the server. This version check tries to ensure that if a version mismatch happens, there will be an informative error message rather than a random crash. --- src/pulsecore/module.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/pulsecore/module.c b/src/pulsecore/module.c index 15a54b6ec..040886d2d 100644 --- a/src/pulsecore/module.c +++ b/src/pulsecore/module.c @@ -45,6 +45,7 @@ #define PA_SYMBOL_LOAD_ONCE "pa__load_once" #define PA_SYMBOL_GET_N_USED "pa__get_n_used" #define PA_SYMBOL_GET_DEPRECATE "pa__get_deprecated" +#define PA_SYMBOL_GET_VERSION "pa__get_version" bool pa_module_exists(const char *name) { const char *paths, *state = NULL; @@ -113,6 +114,7 @@ void pa_module_hook_connect(pa_module *m, pa_hook *hook, pa_hook_priority_t prio int pa_module_load(pa_module** module, pa_core *c, const char *name, const char *argument) { pa_module *m = NULL; + const char *(*get_version)(void); bool (*load_once)(void); const char* (*get_deprecated)(void); pa_modinfo *mi; @@ -147,6 +149,21 @@ int pa_module_load(pa_module** module, pa_core *c, const char *name, const char goto fail; } + if ((get_version = (const char *(*)(void)) pa_load_sym(m->dl, name, PA_SYMBOL_GET_VERSION))) { + const char *version = get_version(); + + if (!pa_safe_streq(version, PACKAGE_VERSION)) { + pa_log("Module \"%s\" version (%s) doesn't match the expected version (%s).", + name, pa_strnull(version), PACKAGE_VERSION); + errcode = -PA_ERR_IO; + goto fail; + } + } else { + pa_log("Symbol \"%s\" not found in module \"%s\".", PA_SYMBOL_GET_VERSION, name); + errcode = -PA_ERR_IO; + goto fail; + } + if ((load_once = (bool (*)(void)) pa_load_sym(m->dl, name, PA_SYMBOL_LOAD_ONCE))) { m->load_once = load_once(); -- cgit v1.2.1