The branch, master has been updated via 24e5973 swrap: Fix a TODO via 74e9e13 Remove thread-safety task from TODO via dd2f1b0 cmake: Disable deep binding for helgrind via e7c9380 swrap: Add env variable to disable deep binding from cf436b6 swrap: Use #ifdef instead of #if for config.h definitions
https://git.samba.org/?p=socket_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 24e597330ec6fbbdc149d798e70d6ed48729bd84 Author: Anoop C S <anoo...@redhat.com> Date: Thu Dec 6 11:16:15 2018 +0530 swrap: Fix a TODO Use realpath(3) instead of strncmp(3) Signed-off-by: Anoop C S <anoo...@redhat.com> Reviewed-by: Ralph Boehme <s...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 74e9e13c38eeda6b31a0bf971e03d2d79eb81681 Author: Anoop C S <anoo...@redhat.com> Date: Thu Dec 6 11:15:46 2018 +0530 Remove thread-safety task from TODO Signed-off-by: Anoop C S <anoo...@redhat.com> Reviewed-by: Ralph Boehme <s...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit dd2f1b001de4a8e70f7c6fa52734b2a82bd2b566 Author: Andreas Schneider <a...@samba.org> Date: Wed Nov 28 09:23:52 2018 +0100 cmake: Disable deep binding for helgrind Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit e7c9380faf0f0557c202119f960026f8700667ee Author: Andreas Schneider <a...@samba.org> Date: Wed Nov 28 09:20:58 2018 +0100 swrap: Add env variable to disable deep binding Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> ----------------------------------------------------------------------- Summary of changes: TODO | 2 -- doc/socket_wrapper.1 | 9 +++-- doc/socket_wrapper.1.txt | 7 +++- src/socket_wrapper.c | 93 +++++++++++++++++++++++++++++++++++------------- tests/CMakeLists.txt | 2 +- 5 files changed, 83 insertions(+), 30 deletions(-) Changeset truncated at 500 lines: diff --git a/TODO b/TODO index 147c166..4a851e6 100644 --- a/TODO +++ b/TODO @@ -10,7 +10,6 @@ Library: --------- Goals: -* Thread safety * The proposed way ==> - fd-passing for tcp sockets (for free) Approach: - tdb "in small". So a "db file". @@ -30,4 +29,3 @@ Testing: * Add a test for sento() to broadcast 255.255.255.255. * Add a test to check that read/readv/send/ only work on connected sockets. * Add unit tests for conversion functions like convert_in_un_remote(). -* Add threaded tests. diff --git a/doc/socket_wrapper.1 b/doc/socket_wrapper.1 index 7e10224..a064eed 100644 --- a/doc/socket_wrapper.1 +++ b/doc/socket_wrapper.1 @@ -2,12 +2,12 @@ .\" Title: socket_wrapper .\" Author: Samba Team .\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/> -.\" Date: 2018-06-26 +.\" Date: 2018-11-28 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "SOCKET_WRAPPER" "1" "2018\-06\-26" "\ \&" "\ \&" +.TH "SOCKET_WRAPPER" "1" "2018\-11\-28" "\ \&" "\ \&" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- @@ -147,6 +147,11 @@ If you need to see what is going on in socket_wrapper itself or try to find a bu 3 = TRACE .RE .RE +.PP +\fBSOCKET_WRAPPER_DISABLE_DEEPBIND\fR +.RS 4 +This allows you to disable deep binding in socket_wrapper\&. This is useful for running valgrind tools or sanitizers like (address, undefined, thread)\&. +.RE .SH "EXAMPLE" .sp .if n \{\ diff --git a/doc/socket_wrapper.1.txt b/doc/socket_wrapper.1.txt index 583b50a..da16c6d 100644 --- a/doc/socket_wrapper.1.txt +++ b/doc/socket_wrapper.1.txt @@ -1,6 +1,6 @@ socket_wrapper(1) ================= -:revdate: 2018-06-26 +:revdate: 2018-11-28 :author: Samba Team NAME @@ -78,6 +78,11 @@ debug symbols. - 2 = DEBUG - 3 = TRACE +*SOCKET_WRAPPER_DISABLE_DEEPBIND*:: + +This allows you to disable deep binding in socket_wrapper. This is useful for +running valgrind tools or sanitizers like (address, undefined, thread). + EXAMPLE ------- diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index ca0a833..de5cc7a 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -555,7 +555,7 @@ struct swrap { static struct swrap swrap; /* prototypes */ -static const char *socket_wrapper_dir(void); +static char *socket_wrapper_dir(void); #define LIBC_NAME "libc.so" @@ -587,15 +587,25 @@ static void *swrap_load_lib_handle(enum swrap_lib lib) int i; #ifdef RTLD_DEEPBIND - const char *env = getenv("LD_PRELOAD"); + const char *env_preload = getenv("LD_PRELOAD"); + const char *env_deepbind = getenv("SOCKET_WRAPPER_DISABLE_DEEPBIND"); + bool enable_deepbind = true; /* Don't do a deepbind if we run with libasan */ - if (env != NULL && strlen(env) < 1024) { - const char *p = strstr(env, "libasan.so"); - if (p == NULL) { - flags |= RTLD_DEEPBIND; + if (env_preload != NULL && strlen(env_preload) < 1024) { + const char *p = strstr(env_preload, "libasan.so"); + if (p != NULL) { + enable_deepbind = false; } } + + if (env_deepbind != NULL && strlen(env_deepbind) >= 1) { + enable_deepbind = false; + } + + if (enable_deepbind) { + flags |= RTLD_DEEPBIND; + } #endif switch (lib) { @@ -1274,19 +1284,25 @@ static void swrap_set_next_free(struct socket_info *si, int next_free) sic->meta.next_free = next_free; } -static const char *socket_wrapper_dir(void) +static char *socket_wrapper_dir(void) { - const char *s = getenv("SOCKET_WRAPPER_DIR"); + char *swrap_dir = NULL; + char *s = getenv("SOCKET_WRAPPER_DIR"); + if (s == NULL) { return NULL; } - /* TODO use realpath(3) here, when we add support for threads */ - if (strncmp(s, "./", 2) == 0) { - s += 2; + + swrap_dir = realpath(s, NULL); + if (swrap_dir == NULL) { + SWRAP_LOG(SWRAP_LOG_ERROR, + "Unable to resolve socket_wrapper dir path: %s", + strerror(errno)); + return NULL; } - SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", s); - return s; + SWRAP_LOG(SWRAP_LOG_TRACE, "socket_wrapper_dir: %s", swrap_dir); + return swrap_dir; } static unsigned int socket_wrapper_mtu(void) @@ -1491,12 +1507,14 @@ done: bool socket_wrapper_enabled(void) { - const char *s = socket_wrapper_dir(); + char *s = socket_wrapper_dir(); if (s == NULL) { return false; } + SAFE_FREE(s); + socket_wrapper_init_sockets(); return true; @@ -1702,6 +1720,7 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i unsigned int prt; unsigned int iface; int is_bcast = 0; + char *swrap_dir = NULL; if (bcast) *bcast = 0; @@ -1800,18 +1819,23 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i return -1; } + swrap_dir = socket_wrapper_dir(); + if (is_bcast) { - snprintf(un->sun_path, sizeof(un->sun_path), "%s/EINVAL", - socket_wrapper_dir()); + snprintf(un->sun_path, sizeof(un->sun_path), + "%s/EINVAL", swrap_dir); SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path); + SAFE_FREE(swrap_dir); /* the caller need to do more processing */ return 0; } snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); + swrap_dir, type, iface, prt); SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path); + SAFE_FREE(swrap_dir); + return 0; } @@ -1823,6 +1847,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in unsigned int iface; struct stat st; int is_bcast = 0; + char *swrap_dir = NULL; if (bcast) *bcast = 0; @@ -1964,11 +1989,13 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in return -1; } + swrap_dir = socket_wrapper_dir(); + if (prt == 0) { /* handle auto-allocation of ephemeral ports */ for (prt = 5001; prt < 10000; prt++) { snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); + swrap_dir, type, iface, prt); if (stat(un->sun_path, &st) == 0) continue; set_port(si->family, prt, &si->myname); @@ -1976,15 +2003,20 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in break; } + if (prt == 10000) { errno = ENFILE; + SAFE_FREE(swrap_dir); return -1; } } snprintf(un->sun_path, sizeof(un->sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); + swrap_dir, type, iface, prt); SWRAP_LOG(SWRAP_LOG_DEBUG, "un path [%s]", un->sun_path); + + SAFE_FREE(swrap_dir); + return 0; } @@ -3446,6 +3478,7 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family) int ret; int port; struct stat st; + char *swrap_dir = NULL; swrap_mutex_lock(&autobind_start_mutex); @@ -3531,11 +3564,13 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family) autobind_start = 10000; } + swrap_dir = socket_wrapper_dir(); + for (i = 0; i < SOCKET_MAX_SOCKETS; i++) { port = autobind_start + i; snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path), - "%s/"SOCKET_FORMAT, socket_wrapper_dir(), - type, socket_wrapper_default_iface(), port); + "%s/"SOCKET_FORMAT, swrap_dir, type, + socket_wrapper_default_iface(), port); if (stat(un_addr.sa.un.sun_path, &st) == 0) continue; ret = libc_bind(fd, &un_addr.sa.s, un_addr.sa_socklen); @@ -3567,6 +3602,7 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family) ret = 0; done: + SAFE_FREE(swrap_dir); swrap_mutex_unlock(&autobind_start_mutex); return ret; } @@ -5329,14 +5365,16 @@ static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, unsigned int iface; unsigned int prt = ntohs(((const struct sockaddr_in *)(const void *)to)->sin_port); char type; + char *swrap_dir = NULL; type = SOCKET_TYPE_CHAR_UDP; + swrap_dir = socket_wrapper_dir(); + for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { snprintf(un_addr.sa.un.sun_path, sizeof(un_addr.sa.un.sun_path), - "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); + "%s/"SOCKET_FORMAT, swrap_dir, type, iface, prt); if (stat(un_addr.sa.un.sun_path, &st) != 0) continue; /* ignore the any errors in broadcast sends */ @@ -5348,6 +5386,8 @@ static ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, un_addr.sa_socklen); } + SAFE_FREE(swrap_dir); + SWRAP_LOCK_SI(si); swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len); @@ -5808,6 +5848,7 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags) off_t ofs = 0; size_t avail = 0; size_t remain; + char *swrap_dir = NULL; for (i = 0; i < (size_t)msg.msg_iovlen; i++) { avail += msg.msg_iov[i].iov_len; @@ -5833,9 +5874,11 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags) type = SOCKET_TYPE_CHAR_UDP; + swrap_dir = socket_wrapper_dir(); + for(iface=0; iface <= MAX_WRAPPED_INTERFACES; iface++) { snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/"SOCKET_FORMAT, - socket_wrapper_dir(), type, iface, prt); + swrap_dir, type, iface, prt); if (stat(un_addr.sun_path, &st) != 0) continue; msg.msg_name = &un_addr; /* optional address */ @@ -5845,6 +5888,8 @@ static ssize_t swrap_sendmsg(int s, const struct msghdr *omsg, int flags) libc_sendmsg(s, &msg, flags); } + SAFE_FREE(swrap_dir); + SWRAP_LOCK_SI(si); swrap_pcap_dump_packet(si, to, SWRAP_SENDTO, buf, len); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1da839c..46a81c9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -127,7 +127,7 @@ if (HELGRIND_TESTING) TEST ${_HELGRIND_TEST} PROPERTY - ENVIRONMENT LD_PRELOAD=${SOCKET_WRAPPER_LOCATION}) + ENVIRONMENT LD_PRELOAD=${SOCKET_WRAPPER_LOCATION} SOCKET_WRAPPER_DISABLE_DEEPBIND=1) endif() endforeach() endif() -- Socket Wrapper Repository