From: Willy Tarreau Date: Sun, 19 Jun 2022 14:41:59 +0000 (+0200) Subject: MEDIUM: debug: add a tainted flag when a shared library is loaded X-Git-Tag: v2.7-dev1~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=40dde2d5c15721fe22bce7ed4272f2db454883f4;p=thirdparty%2Fhaproxy.git 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/include/haproxy/bug.h b/include/haproxy/bug.h index 85d048d556..a4980af8a9 100644 --- a/include/haproxy/bug.h +++ b/include/haproxy/bug.h @@ -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 */ diff --git a/src/tools.c b/src/tools.c index 74903efdae..5a35027502 100644 --- a/src/tools.c +++ b/src/tools.c @@ -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 */