diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/socket_wrapper/socket_wrapper.c | 45 | ||||
-rw-r--r-- | third_party/socket_wrapper/wscript | 3 | ||||
-rw-r--r-- | third_party/uid_wrapper/uid_wrapper.c | 58 | ||||
-rw-r--r-- | third_party/uid_wrapper/wscript | 4 |
4 files changed, 105 insertions, 5 deletions
diff --git a/third_party/socket_wrapper/socket_wrapper.c b/third_party/socket_wrapper/socket_wrapper.c index c759d35..37799c8 100644 --- a/third_party/socket_wrapper/socket_wrapper.c +++ b/third_party/socket_wrapper/socket_wrapper.c @@ -1388,6 +1388,9 @@ static ssize_t libc_writev(int fd, const struct iovec *iov, int iovcnt) return swrap.libc.symbols._libc_writev.f(fd, iov, iovcnt); } +/* JEMALLOC: This tells socket_wrapper if it should handle syscall() */ +static bool swrap_handle_syscall; + #ifdef HAVE_SYSCALL DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE static long int libc_vsyscall(long int sysno, va_list va) @@ -1396,7 +1399,27 @@ static long int libc_vsyscall(long int sysno, va_list va) long int rc; int i; - swrap_bind_symbol_all(); + /* + * JEMALLOC: + * + * This is a workaround to prevent a deadlock in jemalloc calling + * malloc_init() twice. The first allocation call will trigger a + * malloc_init() of jemalloc. The functions calls syscall(SYS_open, ...) + * so it goes to socket or uid wrapper. In this code path we need to + * avoid any allocation calls. This will prevent the deadlock. + * + * We also need to avoid dlopen() as that would trigger the recursion + * into malloc_init(), so we use dlsym(RTLD_NEXT), until we reached + * swrap_constructor() or any real socket call at that time + * swrap_bind_symbol_all() will replace the function pointer again after + * dlopen of libc. + */ + if (swrap_handle_syscall) { + swrap_bind_symbol_all(); + } else if (swrap.libc.symbols._libc_syscall.obj == NULL) { + swrap.libc.symbols._libc_syscall.obj = dlsym(RTLD_NEXT, + "syscall"); + } for (i = 0; i < 8; i++) { args[i] = va_arg(va, long int); @@ -1517,6 +1540,8 @@ static void __swrap_bind_symbol_all_once(void) swrap_bind_symbol_rtld_default_optional(uid_wrapper_syscall_valid); swrap_bind_symbol_rtld_default_optional(uid_wrapper_syscall_va); #endif + + swrap_handle_syscall = true; } static void swrap_bind_symbol_all(void) @@ -8745,6 +8770,21 @@ long int syscall(long int sysno, ...) va_start(va, sysno); /* + * JEMALLOC: + * + * This is a workaround to prevent a deadlock in jemalloc calling + * malloc_init() twice. The first allocation call will trigger a + * malloc_init() of jemalloc. The functions calls syscall(SYS_open, ...) + * so it goes to socket or uid wrapper. In this code path we need to + * avoid any allocation calls. This will prevent the deadlock. + */ + if (!swrap_handle_syscall) { + rc = libc_vsyscall(sysno, va); + va_end(va); + return rc; + } + + /* * We should only handle the syscall numbers * we care about... */ @@ -8860,6 +8900,9 @@ void swrap_constructor(void) pthread_atfork(&swrap_thread_prepare, &swrap_thread_parent, &swrap_thread_child); + + /* Let socket_wrapper handle syscall() */ + swrap_handle_syscall = true; } /**************************** diff --git a/third_party/socket_wrapper/wscript b/third_party/socket_wrapper/wscript index 9d2210d..cdd3493 100644 --- a/third_party/socket_wrapper/wscript +++ b/third_party/socket_wrapper/wscript @@ -2,7 +2,7 @@ import os -VERSION = "1.4.2" +VERSION = "1.4.3" def configure(conf): @@ -10,6 +10,7 @@ def configure(conf): conf.DEFINE('USING_SYSTEM_SOCKET_WRAPPER', 1) libsocket_wrapper_so_path = 'libsocket_wrapper.so' else: + conf.CHECK_HEADERS('gnu/lib-names.h') if conf.CONFIG_SET("HAVE___THREAD"): conf.DEFINE("HAVE_GCC_THREAD_LOCAL_STORAGE", 1) diff --git a/third_party/uid_wrapper/uid_wrapper.c b/third_party/uid_wrapper/uid_wrapper.c index 5b6a82b..ca578e6 100644 --- a/third_party/uid_wrapper/uid_wrapper.c +++ b/third_party/uid_wrapper/uid_wrapper.c @@ -38,6 +38,10 @@ #include <pthread.h> +#ifdef HAVE_GNU_LIB_NAMES_H +#include <gnu/lib-names.h> +#endif + #ifdef HAVE_GCC_THREAD_LOCAL_STORAGE # define UWRAP_THREAD __thread #else @@ -558,6 +562,13 @@ static void *uwrap_load_lib_handle(enum uwrap_lib lib) switch (lib) { case UWRAP_LIBC: handle = uwrap.libc.handle; +#ifdef LIBC_SO + if (handle == NULL) { + handle = dlopen(LIBC_SO, flags); + + uwrap.libc.handle = handle; + } +#endif if (handle == NULL) { for (i = 10; i >= 0; i--) { char soname[256] = {0}; @@ -656,6 +667,9 @@ static void *_uwrap_bind_symbol(enum uwrap_lib lib, const char *fn_name) dlsym(RTLD_DEFAULT, #sym_name); \ } +/* JEMALLOC: This tells uid_wrapper if it should handle syscall() */ +static bool uwrap_handle_syscall; + /* DO NOT call this function during library initialization! */ static void __uwrap_bind_symbol_all_once(void) { @@ -699,6 +713,8 @@ static void __uwrap_bind_symbol_all_once(void) #endif uwrap_bind_symbol_libpthread(pthread_create); uwrap_bind_symbol_libpthread(pthread_exit); + + uwrap_handle_syscall = true; } static void uwrap_bind_symbol_all(void) @@ -863,7 +879,27 @@ static long int libc_vsyscall(long int sysno, va_list va) long int rc; int i; - uwrap_bind_symbol_all(); + /* + * JEMALLOC: + * + * This is a workaround to prevent a deadlock in jemalloc calling + * malloc_init() twice. The first allocation call will trigger a + * malloc_init() of jemalloc. The functions calls syscall(SYS_open, ...) + * so it goes to socket or uid wrapper. In this code path we need to + * avoid any allocation calls. This will prevent the deadlock. + * + * We also need to avoid dlopen() as that would trigger the recursion + * into malloc_init(), so we use dlsym(RTLD_NEXT), until we reached + * swrap_constructor() or any real socket call at that time + * swrap_bind_symbol_all() will replace the function pointer again after + * dlopen of libc. + */ + if (uwrap_handle_syscall) { + uwrap_bind_symbol_all(); + } else if (uwrap.libc.symbols._libc_syscall.obj == NULL) { + uwrap.libc.symbols._libc_syscall.obj = dlsym(RTLD_NEXT, + "syscall"); + } for (i = 0; i < 8; i++) { args[i] = va_arg(va, long int); @@ -1375,7 +1411,7 @@ static void uwrap_init_env(struct uwrap_thread *id) exit(-1); } - UWRAP_LOG(UWRAP_LOG_DEBUG, "Initalize groups with %s", env); + UWRAP_LOG(UWRAP_LOG_DEBUG, "Initialize groups with %s", env); id->ngroups = ngroups; } } @@ -2709,6 +2745,21 @@ long int syscall (long int sysno, ...) va_start(va, sysno); /* + * JEMALLOC: + * + * This is a workaround to prevent a deadlock in jemalloc calling + * malloc_init() twice. The first allocation call will trigger a + * malloc_init() of jemalloc. The functions calls syscall(SYS_open, ...) + * so it goes to socket or uid wrapper. In this code path we need to + * avoid any allocation calls. This will prevent the deadlock. + */ + if (!uwrap_handle_syscall) { + rc = libc_vsyscall(sysno, va); + va_end(va); + return rc; + } + + /* * We need to check for uwrap related syscall numbers before calling * uid_wrapper_enabled() otherwise we'd deadlock during the freebsd libc * fork() which calls syscall() after invoking uwrap_thread_prepare(). @@ -2821,6 +2872,9 @@ void uwrap_constructor(void) * for main process. */ uwrap_init(); + + /* Let socket_wrapper handle syscall() */ + uwrap_handle_syscall = true; } /**************************** diff --git a/third_party/uid_wrapper/wscript b/third_party/uid_wrapper/wscript index 7b65d93..5af7690 100644 --- a/third_party/uid_wrapper/wscript +++ b/third_party/uid_wrapper/wscript @@ -3,13 +3,15 @@ from waflib import Options import os, sys -VERSION="1.3.0" +VERSION="1.3.1" def configure(conf): if conf.CHECK_UID_WRAPPER(): conf.DEFINE('USING_SYSTEM_UID_WRAPPER', 1) libuid_wrapper_so_path = 'libuid_wrapper.so' else: + conf.CHECK_HEADERS('gnu/lib-names.h') + # check HAVE_GCC_ATOMIC_BUILTINS conf.CHECK_CODE(''' #include <stdbool.h> |