[SCM] Socket Wrapper Repository - branch master updated

Michael Adam obnox at samba.org
Thu Oct 20 09:22:56 UTC 2016


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 <asn at samba.org>
Date:   Thu Oct 20 10:37:18 2016 +0200

    swrap: Handle threads that fork
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

    cmake: Check for constructor attribute
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

    swrap: Make symbol loading thread-safe
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at samba.org>

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

    cmake: Link pthread library headers
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Andreas Schneider <asn at samba.org>

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

    swrap: Fix strict-aliasing issues while loading symbols
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Michael Adam <obnox at 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



More information about the samba-cvs mailing list