MEDIUM: debug: add a tainted flag when a shared library is loaded
Several bug reports were caused by shared libraries being loaded by other
libraries or some Lua code. Such libraries could define alternate symbols
or include dependencies to alternate versions of a library used by haproxy,
making it very hard to understand backtraces and analyze the issue.
Let's intercept dlopen() and set a new TAINTED_SHARED_LIBS flag when it
succeeds, so that "show info" makes it visible that some external libs
were added.
The redefinition is based on the definition of RTLD_DEFAULT or RTLD_NEXT
that were previously used to detect that dlsym() is usable, since we need
it as well. This should be sufficient to catch most situations.
diff --git a/src/tools.c b/src/tools.c
index 74903ef..5a35027 100644
--- a/src/tools.c
+++ b/src/tools.c
@@ -5802,6 +5802,36 @@
return 1;
}
+#if defined(RTLD_DEFAULT) || defined(RTLD_NEXT)
+/* redefine dlopen() so that we can detect unexpected replacement of some
+ * critical symbols, typically init/alloc/free functions coming from alternate
+ * libraries. When called, a tainted flag is set (TAINTED_SHARED_LIBS).
+ */
+void *dlopen(const char *filename, int flags)
+{
+ static void *(*_dlopen)(const char *filename, int flags);
+ void *ret;
+
+ if (!_dlopen) {
+ _dlopen = get_sym_next_addr("dlopen");
+ if (!_dlopen || _dlopen == dlopen) {
+ _dlopen = NULL;
+ return NULL;
+ }
+ }
+
+
+ /* now open the requested lib */
+ ret = _dlopen(filename, flags);
+ if (!ret)
+ return ret;
+
+ mark_tainted(TAINTED_SHARED_LIBS);
+
+ return ret;
+}
+#endif
+
static int init_tools_per_thread()
{
/* Let's make each thread start from a different position */