]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: debug: add a tainted flag when a shared library is loaded
authorWilly Tarreau <w@1wt.eu>
Sun, 19 Jun 2022 14:41:59 +0000 (16:41 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 19 Jun 2022 15:58:32 +0000 (17:58 +0200)
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.

include/haproxy/bug.h
src/tools.c

index 85d048d556766c0b63bbd4adf1e7031fe024bcbb..a4980af8a9b5c6be0275f93ff222e428093700f0 100644 (file)
@@ -200,6 +200,7 @@ enum tainted_flags {
        TAINTED_CLI_EXPERIMENTAL_MODE  = 0x00000008,
        TAINTED_WARN                   = 0x00000010, /* a WARN_ON triggered */
        TAINTED_BUG                    = 0x00000020, /* a BUG_ON triggered */
+       TAINTED_SHARED_LIBS            = 0x00000040, /* a shared library was loaded */
 };
 
 /* this is a bit field made of TAINTED_*, and is declared in haproxy.c */
index 74903efdaeead27c8c45ef7fd535eb6091794d28..5a35027502c2b7deb1d13755ca83cd4c386ff358 100644 (file)
@@ -5802,6 +5802,36 @@ int openssl_compare_current_name(const char *name)
        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 */