]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
third_party: Update uid_wrapper to version 1.3.1
authorAndreas Schneider <asn@samba.org>
Thu, 13 Jun 2024 05:41:41 +0000 (07:41 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 9 Jul 2024 13:27:12 +0000 (13:27 +0000)
This fixes issues with bind compiled with jemalloc.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15660

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
(cherry picked from commit f88e60644e76c6310088934439f9c0da0f63905f)

buildtools/wafsamba/samba_third_party.py
third_party/uid_wrapper/uid_wrapper.c
third_party/uid_wrapper/wscript

index 52898486fd9a15d5d7c90c147079e4da72c7ad3e..8fa1756b03be037cdaa3a34902cd971667c231fd 100644 (file)
@@ -39,7 +39,7 @@ Build.BuildContext.CHECK_RESOLV_WRAPPER = CHECK_RESOLV_WRAPPER
 
 @conf
 def CHECK_UID_WRAPPER(conf):
-    return conf.CHECK_BUNDLED_SYSTEM_PKG('uid_wrapper', minversion='1.3.0')
+    return conf.CHECK_BUNDLED_SYSTEM_PKG('uid_wrapper', minversion='1.3.1')
 Build.BuildContext.CHECK_UID_WRAPPER = CHECK_UID_WRAPPER
 
 @conf
index 5b6a82b8fef32d8d03e5fd1110554d113ca9bd2e..ca578e61f2e7cd7c65cf27cd2b7714566d3f2a6d 100644 (file)
 
 #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;
        }
 }
@@ -2708,6 +2744,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
@@ -2821,6 +2872,9 @@ void uwrap_constructor(void)
         * for main process.
         */
        uwrap_init();
+
+       /* Let socket_wrapper handle syscall() */
+       uwrap_handle_syscall = true;
 }
 
 /****************************
index c92388184665957239626e217f0d90f828f9b97d..36f4e53df47ec094278f1be647fe1e1558d6b88a 100644 (file)
@@ -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>