The branch, master has been updated
       via  d8cf3b0 swrap: Handle threads that fork
       via  c989bbc cmake: Check for constructor attribute
       via  f5cddcd swrap: Make symbol loading thread-safe
       via  201811d cmake: Link pthread library headers
       via  3507e18 swrap: Fix strict-aliasing issues while loading symbols
      from  b61f5df tests: Add a test for max_sockets

https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d8cf3b0ca8ce24aaf19e4692882dadffa921f763
Author: Andreas Schneider <a...@samba.org>
Date:   Thu Oct 20 10:37:18 2016 +0200

    swrap: Handle threads that fork
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit c989bbc9f6afaad9e4b26501d57d7acb1297d1cb
Author: Andreas Schneider <a...@samba.org>
Date:   Thu Oct 20 10:35:50 2016 +0200

    cmake: Check for constructor attribute
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit f5cddcd300b779131662519d56ae90fcebe459e1
Author: Andreas Schneider <a...@samba.org>
Date:   Thu Oct 20 10:22:40 2016 +0200

    swrap: Make symbol loading thread-safe
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

commit 201811dc614a4787482c3bb2fa14f47112a05a34
Author: Michael Adam <ob...@samba.org>
Date:   Sun Sep 18 20:28:06 2016 +0200

    cmake: Link pthread library headers
    
    Signed-off-by: Michael Adam <ob...@samba.org>
    Reviewed-by: Andreas Schneider <a...@samba.org>

commit 3507e186d08fa8170a3499c9e69a49aa60ff9dcd
Author: Andreas Schneider <a...@samba.org>
Date:   Thu Oct 20 10:56:35 2016 +0200

    swrap: Fix strict-aliasing issues while loading symbols
    
    Signed-off-by: Andreas Schneider <a...@samba.org>
    Reviewed-by: Michael Adam <ob...@samba.org>

-----------------------------------------------------------------------

Summary of changes:
 ConfigureChecks.cmake |  12 ++
 config.h.cmake        |   1 +
 src/CMakeLists.txt    |   2 +-
 src/socket_wrapper.c  | 434 +++++++++++++++++++++++++++++++++-----------------
 tests/CMakeLists.txt  |   3 +-
 5 files changed, 306 insertions(+), 146 deletions(-)


Changeset truncated at 500 lines:

diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 48455ef..71b34ce 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -172,6 +172,18 @@ int main(void) {
 }" HAVE_SOCKADDR_STORAGE)
 
 check_c_source_compiles("
+void test_constructor_attribute(void) __attribute__ ((constructor));
+
+void test_constructor_attribute(void)
+{
+    return;
+}
+
+int main(void) {
+    return 0;
+}" HAVE_CONSTRUCTOR_ATTRIBUTE)
+
+check_c_source_compiles("
 void test_destructor_attribute(void) __attribute__ ((destructor));
 
 void test_destructor_attribute(void)
diff --git a/config.h.cmake b/config.h.cmake
index a9b8ce8..6786b8a 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -58,6 +58,7 @@
 /**************************** OPTIONS ****************************/
 
 #cmakedefine HAVE_GCC_THREAD_LOCAL_STORAGE 1
+#cmakedefine HAVE_CONSTRUCTOR_ATTRIBUTE 1
 #cmakedefine HAVE_DESTRUCTOR_ATTRIBUTE 1
 #cmakedefine HAVE_ADDRESS_SANITIZER_ATTRIBUTE 1
 #cmakedefine HAVE_SOCKADDR_STORAGE 1
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4b22d77..3b4d7d0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -4,7 +4,7 @@ include_directories(${CMAKE_BINARY_DIR})
 
 add_library(socket_wrapper SHARED socket_wrapper.c)
 
-target_link_libraries(socket_wrapper ${SWRAP_REQUIRED_LIBRARIES})
+target_link_libraries(socket_wrapper ${SWRAP_REQUIRED_LIBRARIES} 
${CMAKE_THREAD_LIBS_INIT})
 
 install(
   TARGETS
diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c
index 84dfc07..6679d5c 100644
--- a/src/socket_wrapper.c
+++ b/src/socket_wrapper.c
@@ -79,6 +79,7 @@
 #ifdef HAVE_RPC_RPC_H
 #include <rpc/rpc.h>
 #endif
+#include <pthread.h>
 
 enum swrap_dbglvl_e {
        SWRAP_LOG_ERROR = 0,
@@ -94,6 +95,12 @@ enum swrap_dbglvl_e {
 #define PRINTF_ATTRIBUTE(a,b)
 #endif /* HAVE_FUNCTION_ATTRIBUTE_FORMAT */
 
+#ifdef HAVE_CONSTRUCTOR_ATTRIBUTE
+#define CONSTRUCTOR_ATTRIBUTE __attribute__ ((constructor))
+#else
+#define CONSTRUCTOR_ATTRIBUTE
+#endif /* HAVE_CONSTRUCTOR_ATTRIBUTE */
+
 #ifdef HAVE_DESTRUCTOR_ATTRIBUTE
 #define DESTRUCTOR_ATTRIBUTE __attribute__ ((destructor))
 #else
@@ -152,6 +159,22 @@ enum swrap_dbglvl_e {
 # endif
 #endif
 
+/* Macros for accessing mutexes */
+# define SWRAP_LOCK(m) do { \
+       pthread_mutex_lock(&(m ## _mutex)); \
+} while(0)
+
+# define SWRAP_UNLOCK(m) do { \
+       pthread_mutex_unlock(&(m ## _mutex)); \
+} while(0)
+
+/* Add new global locks here please */
+# define SWRAP_LOCK_ALL \
+       SWRAP_LOCK(libc_symbol_binding); \
+
+# define SWRAP_UNLOCK_ALL \
+       SWRAP_UNLOCK(libc_symbol_binding); \
+
 
 #define SWRAP_DLIST_ADD(list,item) do { \
        if (!(list)) { \
@@ -305,9 +328,14 @@ static size_t max_sockets = 0;
  */
 static struct socket_info_fd *socket_fds;
 
+/* The mutex for accessing the global libc.symbols */
+static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 /* Function prototypes */
 
 bool socket_wrapper_enabled(void);
+
+void swrap_constructor(void) CONSTRUCTOR_ATTRIBUTE;
 void swrap_destructor(void) DESTRUCTOR_ATTRIBUTE;
 
 #ifdef NDEBUG
@@ -368,86 +396,133 @@ static void swrap_log(enum swrap_dbglvl_e dbglvl,
 
 #include <dlfcn.h>
 
-struct swrap_libc_fns {
 #ifdef HAVE_ACCEPT4
-       int (*libc_accept4)(int sockfd,
-                          struct sockaddr *addr,
-                          socklen_t *addrlen,
-                          int flags);
+typedef int (*__libc_accept4)(int sockfd,
+                             struct sockaddr *addr,
+                             socklen_t *addrlen,
+                             int flags);
 #else
-       int (*libc_accept)(int sockfd,
-                          struct sockaddr *addr,
-                          socklen_t *addrlen);
+typedef int (*__libc_accept)(int sockfd,
+                            struct sockaddr *addr,
+                            socklen_t *addrlen);
 #endif
-       int (*libc_bind)(int sockfd,
-                        const struct sockaddr *addr,
-                        socklen_t addrlen);
-       int (*libc_close)(int fd);
-       int (*libc_connect)(int sockfd,
-                           const struct sockaddr *addr,
-                           socklen_t addrlen);
-       int (*libc_dup)(int fd);
-       int (*libc_dup2)(int oldfd, int newfd);
-       int (*libc_fcntl)(int fd, int cmd, ...);
-       FILE *(*libc_fopen)(const char *name, const char *mode);
+typedef int (*__libc_bind)(int sockfd,
+                          const struct sockaddr *addr,
+                          socklen_t addrlen);
+typedef int (*__libc_close)(int fd);
+typedef int (*__libc_connect)(int sockfd,
+                             const struct sockaddr *addr,
+                             socklen_t addrlen);
+typedef int (*__libc_dup)(int fd);
+typedef int (*__libc_dup2)(int oldfd, int newfd);
+typedef int (*__libc_fcntl)(int fd, int cmd, ...);
+typedef FILE *(*__libc_fopen)(const char *name, const char *mode);
 #ifdef HAVE_EVENTFD
-       int (*libc_eventfd)(int count, int flags);
+typedef int (*__libc_eventfd)(int count, int flags);
 #endif
-       int (*libc_getpeername)(int sockfd,
-                               struct sockaddr *addr,
-                               socklen_t *addrlen);
-       int (*libc_getsockname)(int sockfd,
-                               struct sockaddr *addr,
-                               socklen_t *addrlen);
-       int (*libc_getsockopt)(int sockfd,
+typedef int (*__libc_getpeername)(int sockfd,
+                                 struct sockaddr *addr,
+                                 socklen_t *addrlen);
+typedef int (*__libc_getsockname)(int sockfd,
+                                 struct sockaddr *addr,
+                                 socklen_t *addrlen);
+typedef int (*__libc_getsockopt)(int sockfd,
                               int level,
                               int optname,
                               void *optval,
                               socklen_t *optlen);
-       int (*libc_ioctl)(int d, unsigned long int request, ...);
-       int (*libc_listen)(int sockfd, int backlog);
-       int (*libc_open)(const char *pathname, int flags, mode_t mode);
-       int (*libc_pipe)(int pipefd[2]);
-       int (*libc_read)(int fd, void *buf, size_t count);
-       ssize_t (*libc_readv)(int fd, const struct iovec *iov, int iovcnt);
-       int (*libc_recv)(int sockfd, void *buf, size_t len, int flags);
-       int (*libc_recvfrom)(int sockfd,
+typedef int (*__libc_ioctl)(int d, unsigned long int request, ...);
+typedef int (*__libc_listen)(int sockfd, int backlog);
+typedef int (*__libc_open)(const char *pathname, int flags, mode_t mode);
+typedef int (*__libc_pipe)(int pipefd[2]);
+typedef int (*__libc_read)(int fd, void *buf, size_t count);
+typedef ssize_t (*__libc_readv)(int fd, const struct iovec *iov, int iovcnt);
+typedef int (*__libc_recv)(int sockfd, void *buf, size_t len, int flags);
+typedef int (*__libc_recvfrom)(int sockfd,
                             void *buf,
                             size_t len,
                             int flags,
                             struct sockaddr *src_addr,
                             socklen_t *addrlen);
-       int (*libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
-       int (*libc_send)(int sockfd, const void *buf, size_t len, int flags);
-       int (*libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
-       int (*libc_sendto)(int sockfd,
+typedef int (*__libc_recvmsg)(int sockfd, const struct msghdr *msg, int flags);
+typedef int (*__libc_send)(int sockfd, const void *buf, size_t len, int flags);
+typedef int (*__libc_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
+typedef int (*__libc_sendto)(int sockfd,
                           const void *buf,
                           size_t len,
                           int flags,
                           const  struct sockaddr *dst_addr,
                           socklen_t addrlen);
-       int (*libc_setsockopt)(int sockfd,
+typedef int (*__libc_setsockopt)(int sockfd,
                               int level,
                               int optname,
                               const void *optval,
                               socklen_t optlen);
 #ifdef HAVE_SIGNALFD
-       int (*libc_signalfd)(int fd, const sigset_t *mask, int flags);
+typedef int (*__libc_signalfd)(int fd, const sigset_t *mask, int flags);
 #endif
-       int (*libc_socket)(int domain, int type, int protocol);
-       int (*libc_socketpair)(int domain, int type, int protocol, int sv[2]);
+typedef int (*__libc_socket)(int domain, int type, int protocol);
+typedef int (*__libc_socketpair)(int domain, int type, int protocol, int 
sv[2]);
 #ifdef HAVE_TIMERFD_CREATE
-       int (*libc_timerfd_create)(int clockid, int flags);
+typedef int (*__libc_timerfd_create)(int clockid, int flags);
 #endif
-       ssize_t (*libc_write)(int fd, const void *buf, size_t count);
-       ssize_t (*libc_writev)(int fd, const struct iovec *iov, int iovcnt);
+typedef ssize_t (*__libc_write)(int fd, const void *buf, size_t count);
+typedef ssize_t (*__libc_writev)(int fd, const struct iovec *iov, int iovcnt);
+
+#define SWRAP_SYMBOL_ENTRY(i) \
+       union { \
+               __libc_##i f; \
+               void *obj; \
+       } _libc_##i
+
+struct swrap_libc_symbols {
+#ifdef HAVE_ACCEPT4
+       SWRAP_SYMBOL_ENTRY(accept4);
+#else
+       SWRAP_SYMBOL_ENTRY(accept);
+#endif
+       SWRAP_SYMBOL_ENTRY(bind);
+       SWRAP_SYMBOL_ENTRY(close);
+       SWRAP_SYMBOL_ENTRY(connect);
+       SWRAP_SYMBOL_ENTRY(dup);
+       SWRAP_SYMBOL_ENTRY(dup2);
+       SWRAP_SYMBOL_ENTRY(fcntl);
+       SWRAP_SYMBOL_ENTRY(fopen);
+#ifdef HAVE_EVENTFD
+       SWRAP_SYMBOL_ENTRY(eventfd);
+#endif
+       SWRAP_SYMBOL_ENTRY(getpeername);
+       SWRAP_SYMBOL_ENTRY(getsockname);
+       SWRAP_SYMBOL_ENTRY(getsockopt);
+       SWRAP_SYMBOL_ENTRY(ioctl);
+       SWRAP_SYMBOL_ENTRY(listen);
+       SWRAP_SYMBOL_ENTRY(open);
+       SWRAP_SYMBOL_ENTRY(pipe);
+       SWRAP_SYMBOL_ENTRY(read);
+       SWRAP_SYMBOL_ENTRY(readv);
+       SWRAP_SYMBOL_ENTRY(recv);
+       SWRAP_SYMBOL_ENTRY(recvfrom);
+       SWRAP_SYMBOL_ENTRY(recvmsg);
+       SWRAP_SYMBOL_ENTRY(send);
+       SWRAP_SYMBOL_ENTRY(sendmsg);
+       SWRAP_SYMBOL_ENTRY(sendto);
+       SWRAP_SYMBOL_ENTRY(setsockopt);
+#ifdef HAVE_SIGNALFD
+       SWRAP_SYMBOL_ENTRY(signalfd);
+#endif
+       SWRAP_SYMBOL_ENTRY(socket);
+       SWRAP_SYMBOL_ENTRY(socketpair);
+       SWRAP_SYMBOL_ENTRY(timerfd_create);
+       SWRAP_SYMBOL_ENTRY(write);
+       SWRAP_SYMBOL_ENTRY(writev);
 };
 
 struct swrap {
-       void *libc_handle;
-       void *libsocket_handle;
-
-       struct swrap_libc_fns fns;
+       struct {
+               void *handle;
+               void *socket_handle;
+               struct swrap_libc_symbols symbols;
+       } libc;
 };
 
 static struct swrap swrap;
@@ -507,18 +582,18 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
                                }
                        }
 
-                       swrap.libsocket_handle = handle;
+                       swrap.libc.socket_handle = handle;
                }
                break;
 #endif
                /* FALL TROUGH */
        case SWRAP_LIBC:
-               handle = swrap.libc_handle;
+               handle = swrap.libc.handle;
 #ifdef LIBC_SO
                if (handle == NULL) {
                        handle = dlopen(LIBC_SO, flags);
 
-                       swrap.libc_handle = handle;
+                       swrap.libc.handle = handle;
                }
 #endif
                if (handle == NULL) {
@@ -532,14 +607,14 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
                                }
                        }
 
-                       swrap.libc_handle = handle;
+                       swrap.libc.handle = handle;
                }
                break;
        }
 
        if (handle == NULL) {
 #ifdef RTLD_NEXT
-               handle = swrap.libc_handle = swrap.libsocket_handle = RTLD_NEXT;
+               handle = swrap.libc.handle = swrap.libc.socket_handle = 
RTLD_NEXT;
 #else
                SWRAP_LOG(SWRAP_LOG_ERROR,
                          "Failed to dlopen library: %s\n",
@@ -551,7 +626,7 @@ static void *swrap_load_lib_handle(enum swrap_lib lib)
        return handle;
 }
 
-static void *_swrap_load_lib_function(enum swrap_lib lib, const char *fn_name)
+static void *_swrap_bind_symbol(enum swrap_lib lib, const char *fn_name)
 {
        void *handle;
        void *func;
@@ -561,24 +636,43 @@ static void *_swrap_load_lib_function(enum swrap_lib lib, 
const char *fn_name)
        func = dlsym(handle, fn_name);
        if (func == NULL) {
                SWRAP_LOG(SWRAP_LOG_ERROR,
-                               "Failed to find %s: %s\n",
-                               fn_name, dlerror());
+                         "Failed to find %s: %s\n",
+                         fn_name,
+                         dlerror());
                exit(-1);
        }
 
        SWRAP_LOG(SWRAP_LOG_TRACE,
-                       "Loaded %s from %s",
-                       fn_name, swrap_str_lib(lib));
+                 "Loaded %s from %s",
+                 fn_name,
+                 swrap_str_lib(lib));
+
        return func;
 }
 
-#define swrap_load_lib_function(lib, fn_name) \
-       if (swrap.fns.libc_##fn_name == NULL) { \
-               void *swrap_cast_ptr = _swrap_load_lib_function(lib, #fn_name); 
\
-               *(void **) (&swrap.fns.libc_##fn_name) = \
-                       swrap_cast_ptr; \
-       }
+#define swrap_bind_symbol_libc(sym_name) \
+       SWRAP_LOCK(libc_symbol_binding); \
+       if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+               swrap.libc.symbols._libc_##sym_name.obj = \
+                       _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
+       } \
+       SWRAP_UNLOCK(libc_symbol_binding)
+
+#define swrap_bind_symbol_libsocket(sym_name) \
+       SWRAP_LOCK(libc_symbol_binding); \
+       if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+               swrap.libc.symbols._libc_##sym_name.obj = \
+                       _swrap_bind_symbol(SWRAP_LIBSOCKET, #sym_name); \
+       } \
+       SWRAP_UNLOCK(libc_symbol_binding)
 
+#define swrap_bind_symbol_libnsl(sym_name) \
+       SWRAP_LOCK(libc_symbol_binding); \
+       if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
+               swrap.libc.symbols._libc_##sym_name.obj = \
+                       _swrap_bind_symbol(SWRAP_LIBNSL, #sym_name); \
+       } \
+       SWRAP_UNLOCK(libc_symbol_binding)
 
 /*
  * IMPORTANT
@@ -594,18 +688,18 @@ static int libc_accept4(int sockfd,
                        socklen_t *addrlen,
                        int flags)
 {
-       swrap_load_lib_function(SWRAP_LIBSOCKET, accept4);
+       swrap_bind_symbol_libsocket(accept4);
 
-       return swrap.fns.libc_accept4(sockfd, addr, addrlen, flags);
+       return swrap.libc.symbols._libc_accept4.f(sockfd, addr, addrlen, flags);
 }
 
 #else /* HAVE_ACCEPT4 */
 
 static int libc_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
 {
-       swrap_load_lib_function(SWRAP_LIBSOCKET, accept);
+       swrap_bind_symbol_libsocket(accept);
 
-       return swrap.fns.libc_accept(sockfd, addr, addrlen);
+       return swrap.libc.symbols._libc_accept.f(sockfd, addr, addrlen);
 }
 #endif /* HAVE_ACCEPT4 */
 
@@ -613,47 +707,47 @@ static int libc_bind(int sockfd,
                     const struct sockaddr *addr,
                     socklen_t addrlen)
 {
-       swrap_load_lib_function(SWRAP_LIBSOCKET, bind);
+       swrap_bind_symbol_libsocket(bind);
 
-       return swrap.fns.libc_bind(sockfd, addr, addrlen);
+       return swrap.libc.symbols._libc_bind.f(sockfd, addr, addrlen);
 }
 
 static int libc_close(int fd)
 {
-       swrap_load_lib_function(SWRAP_LIBC, close);
+       swrap_bind_symbol_libc(close);
 
-       return swrap.fns.libc_close(fd);
+       return swrap.libc.symbols._libc_close.f(fd);
 }
 
 static int libc_connect(int sockfd,
                        const struct sockaddr *addr,
                        socklen_t addrlen)
 {
-       swrap_load_lib_function(SWRAP_LIBSOCKET, connect);
+       swrap_bind_symbol_libsocket(connect);
 
-       return swrap.fns.libc_connect(sockfd, addr, addrlen);
+       return swrap.libc.symbols._libc_connect.f(sockfd, addr, addrlen);
 }
 
 static int libc_dup(int fd)
 {
-       swrap_load_lib_function(SWRAP_LIBC, dup);
+       swrap_bind_symbol_libc(dup);
 
-       return swrap.fns.libc_dup(fd);
+       return swrap.libc.symbols._libc_dup.f(fd);
 }
 
 static int libc_dup2(int oldfd, int newfd)
 {
-       swrap_load_lib_function(SWRAP_LIBC, dup2);
+       swrap_bind_symbol_libc(dup2);
 
-       return swrap.fns.libc_dup2(oldfd, newfd);
+       return swrap.libc.symbols._libc_dup2.f(oldfd, newfd);
 }
 
 #ifdef HAVE_EVENTFD
 static int libc_eventfd(int count, int flags)
 {
-       swrap_load_lib_function(SWRAP_LIBC, eventfd);
+       swrap_bind_symbol_libc(eventfd);
 
-       return swrap.fns.libc_eventfd(count, flags);
+       return swrap.libc.symbols._libc_eventfd.f(count, flags);
 }
 #endif
 
@@ -664,18 +758,18 @@ static int libc_vfcntl(int fd, int cmd, va_list ap)
        int rc;
        int i;
 
-       swrap_load_lib_function(SWRAP_LIBC, fcntl);
+       swrap_bind_symbol_libc(fcntl);
 
        for (i = 0; i < 4; i++) {
                args[i] = va_arg(ap, long int);
        }
 
-       rc = swrap.fns.libc_fcntl(fd,
-                                 cmd,
-                                 args[0],
-                                 args[1],
-                                 args[2],
-                                 args[3]);
+       rc = swrap.libc.symbols._libc_fcntl.f(fd,
+                                             cmd,
+                                             args[0],


-- 
Socket Wrapper Repository

Reply via email to