From 6f78600e9600f413ebdf532e154d8946725d83fd Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 27 Apr 2021 12:13:04 -0400 Subject: [PATCH] Detect unsupported use of .so.0 and .so.1 libraries within same process Abort process if unsupported use of liblttng-ust and liblttng-ust-tracepoint .so.0 vs .so.1 within the same process is detected. Signed-off-by: Mathieu Desnoyers Change-Id: I2842ec43bf8840ddf88e0dd04bddb4c9e04e3a04 --- src/lib/lttng-ust-tracepoint/tracepoint.c | 42 +++++++++++++++++++++++ src/lib/lttng-ust/lttng-ust-comm.c | 41 ++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/src/lib/lttng-ust-tracepoint/tracepoint.c b/src/lib/lttng-ust-tracepoint/tracepoint.c index 38d57cec..12bc561c 100644 --- a/src/lib/lttng-ust-tracepoint/tracepoint.c +++ b/src/lib/lttng-ust-tracepoint/tracepoint.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -607,6 +608,39 @@ static void tracepoint_release_queue_add_old_probes(void *old) } } +/* + * Use a symbol of the previous ABI to detect if liblttng-ust-tracepoint.so.0 + * is loaded in the current process. + */ +#define LTTNG_UST_TRACEPOINT_SONAME_0_SYM "tracepoint_unregister_lib" + +static +void lttng_ust_tracepoint_check_soname_0(void) +{ + if (!dlsym(RTLD_DEFAULT, LTTNG_UST_TRACEPOINT_SONAME_0_SYM)) + return; + + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by lookup of ABI 0 symbol \"%s\" in the Global Symbol Table\n", + LTTNG_UST_TRACEPOINT_SONAME_0_SYM); +} + +/* + * Expose a canary symbol of the previous ABI to ensure we catch uses of a + * liblttng-ust-tracepoint.so.0 dlopen'd after .so.1 has been loaded. Use a + * different symbol than the detection code to ensure we don't detect ourself. + */ +int tracepoint_register_lib(void *arg0 __attribute__((unused)), int arg1 __attribute__((unused))); +int tracepoint_register_lib(void *arg0 __attribute__((unused)), int arg1 __attribute__((unused))) +{ + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by canary symbol \"%s\"\n", __func__); + + return -1; +} + /** * lttng_ust_tracepoint_provider_register - Connect a probe to a tracepoint * @name: tracepoint provider name @@ -623,6 +657,14 @@ int lttng_ust_tracepoint_provider_register(const char *provider_name, const char void *old; int ret = 0; + /* + * Check if we find a symbol of the previous ABI in the current process + * as different ABIs of liblttng-ust can't co-exist in a process. If we + * do so, emit a critical log message which will also abort if the + * LTTNG_UST_ABORT_ON_CRITICAL environment variable is set. + */ + lttng_ust_tracepoint_check_soname_0(); + DBG("Registering probe to tracepoint \"%s:%s\"", provider_name, event_name); pthread_mutex_lock(&tracepoint_mutex); diff --git a/src/lib/lttng-ust/lttng-ust-comm.c b/src/lib/lttng-ust/lttng-ust-comm.c index 5330e5c2..f180c3bc 100644 --- a/src/lib/lttng-ust/lttng-ust-comm.c +++ b/src/lib/lttng-ust/lttng-ust-comm.c @@ -2100,6 +2100,37 @@ void lttng_ust_libc_wrapper_malloc_ctor(void) { } +/* + * Use a symbol of the previous ABI to detect if liblttng-ust.so.0 is loaded in + * the current process. + */ +#define LTTNG_UST_SONAME_0_SYM "ltt_probe_register" + +static +void lttng_ust_check_soname_0(void) +{ + if (!dlsym(RTLD_DEFAULT, LTTNG_UST_SONAME_0_SYM)) + return; + + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by lookup of ABI 0 symbol \"%s\" in the Global Symbol Table\n", + LTTNG_UST_SONAME_0_SYM); +} + +/* + * Expose a canary symbol of the previous ABI to ensure we catch uses of a + * liblttng-ust.so.0 dlopen'd after .so.1 has been loaded. Use a different + * symbol than the detection code to ensure we don't detect ourself. + */ +void init_usterr(void); +void init_usterr(void) +{ + CRIT("Incompatible library ABIs detected within the same process. " + "The process is likely linked against different major soname of LTTng-UST which is unsupported. " + "The detection was triggered by canary symbol \"%s\"\n", __func__); +} + /* * sessiond monitoring thread: monitor presence of global and per-user * sessiond by polling the application common named pipe. @@ -2129,6 +2160,14 @@ void lttng_ust_ctor(void) lttng_ust_loaded = 1; + /* + * Check if we find a symbol of the previous ABI in the current process + * as different ABIs of liblttng-ust can't co-exist in a process. If we + * do so, emit a critical log message which will also abort if the + * LTTNG_UST_ABORT_ON_CRITICAL environment variable is set. + */ + lttng_ust_check_soname_0(); + /* * We need to ensure that the liblttng-ust library is not unloaded to avoid * the unloading of code used by the ust_listener_threads as we can not @@ -2147,6 +2186,8 @@ void lttng_ust_ctor(void) handle = dlopen(LTTNG_UST_LIB_SONAME, RTLD_LAZY | RTLD_NODELETE); if (!handle) { ERR("dlopen of liblttng-ust shared library (%s).", LTTNG_UST_LIB_SONAME); + } else { + DBG("dlopened liblttng-ust shared library (%s).", LTTNG_UST_LIB_SONAME); } /* -- 2.34.1