diff --git a/include/haproxy/bug.h b/include/haproxy/bug.h index 85d048d55..a4980af8a 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 74903efda..5a3502750 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 */