summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanu Kaskinen <tanuk@iki.fi>2020-02-11 09:40:49 +0200
committerGeorg Chini <georg@chini.tk>2020-12-09 10:34:49 +0000
commite43ca00d5255d81d2004bf33f30dab3843e8aa1d (patch)
tree20f968ccbd13656dc9b5c7140f9f79e0d860d6df
parent05f3e8bf9ae7adeb4db8b77c0a92dbb5350d189a (diff)
downloadpulseaudio-e43ca00d5255d81d2004bf33f30dab3843e8aa1d.tar.gz
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.
-rw-r--r--src/pulsecore/module.c17
1 files changed, 17 insertions, 0 deletions
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();