summaryrefslogtreecommitdiffstats
path: root/third_party
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/socket_wrapper/socket_wrapper.c45
-rw-r--r--third_party/socket_wrapper/wscript3
-rw-r--r--third_party/uid_wrapper/uid_wrapper.c58
-rw-r--r--third_party/uid_wrapper/wscript4
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>