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.
This commit is contained in:
Willy Tarreau 2022-06-19 16:41:59 +02:00
parent 0b7b639d7e
commit 40dde2d5c1
2 changed files with 31 additions and 0 deletions

View 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 */

View 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 */