diff options
author | Stefan Metzmacher <metze@samba.org> | 2020-03-10 13:27:27 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2020-03-25 06:58:38 +0000 |
commit | e09c2e118b31968f6618c21eb4a5f952735f19a0 (patch) | |
tree | 8d6f56be4b87b9ddaa885d777dd324882945e920 /third_party | |
parent | 61a6bf82d4cd7b1deecaf41d5d4f7d9e73f168be (diff) | |
download | samba-e09c2e118b31968f6618c21eb4a5f952735f19a0.tar.gz |
third_party: Update socket_wrapper to version 1.2.4
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'third_party')
-rw-r--r-- | third_party/socket_wrapper/socket_wrapper.c | 199 | ||||
-rw-r--r-- | third_party/socket_wrapper/wscript | 10 |
2 files changed, 196 insertions, 13 deletions
diff --git a/third_party/socket_wrapper/socket_wrapper.c b/third_party/socket_wrapper/socket_wrapper.c index a9e2a756fde..cee7c51fc76 100644 --- a/third_party/socket_wrapper/socket_wrapper.c +++ b/third_party/socket_wrapper/socket_wrapper.c @@ -1192,6 +1192,94 @@ static void swrap_bind_symbol_all(void) * SWRAP HELPER FUNCTIONS *********************************************************/ +/* + * We return 127.0.0.0 (default) or 10.53.57.0. + * + * This can be controlled by: + * SOCKET_WRAPPER_IPV4_NETWORK=127.0.0.0 (default) + * or + * SOCKET_WRAPPER_IPV4_NETWORK=10.53.57.0 + */ +static in_addr_t swrap_ipv4_net(void) +{ + static int initialized; + static in_addr_t hv; + const char *net_str = NULL; + struct in_addr nv; + int ret; + + if (initialized) { + return hv; + } + initialized = 1; + + net_str = getenv("SOCKET_WRAPPER_IPV4_NETWORK"); + if (net_str == NULL) { + net_str = "127.0.0.0"; + } + + ret = inet_pton(AF_INET, net_str, &nv); + if (ret <= 0) { + SWRAP_LOG(SWRAP_LOG_ERROR, + "INVALID IPv4 Network [%s]\n", + net_str); + abort(); + } + + hv = ntohl(nv.s_addr); + + switch (hv) { + case 0x7f000000: + /* 127.0.0.0 */ + break; + case 0x0a353900: + /* 10.53.57.0 */ + break; + default: + SWRAP_LOG(SWRAP_LOG_ERROR, + "INVALID IPv4 Network [%s][0x%x] should be " + "127.0.0.0 or 10.53.57.0\n", + net_str, (unsigned)hv); + abort(); + } + + return hv; +} + +/* + * This returns 127.255.255.255 or 10.255.255.255 + */ +static in_addr_t swrap_ipv4_bcast(void) +{ + in_addr_t hv; + + hv = swrap_ipv4_net(); + hv |= IN_CLASSA_HOST; + + return hv; +} + +/* + * This returns 127.0.0.${iface} or 10.53.57.${iface} + */ +static in_addr_t swrap_ipv4_iface(unsigned int iface) +{ + in_addr_t hv; + + if (iface == 0 || iface > MAX_WRAPPED_INTERFACES) { + SWRAP_LOG(SWRAP_LOG_ERROR, + "swrap_ipv4_iface(%u) invalid!\n", + iface); + abort(); + return -1; + } + + hv = swrap_ipv4_net(); + hv |= iface; + + return hv; +} + #ifdef HAVE_IPV6 /* * FD00::5357:5FXX @@ -1442,6 +1530,12 @@ static void socket_wrapper_init_sockets(void) return; } + /* + * Intialize the static cache early before + * any thread is able to start. + */ + (void)swrap_ipv4_net(); + socket_wrapper_init_fds_idx(); /* Needs to be called inside the sockets_mutex lock here. */ @@ -1536,6 +1630,9 @@ static unsigned int socket_wrapper_default_iface(void) static void set_socket_info_index(int fd, int idx) { + SWRAP_LOG(SWRAP_LOG_TRACE, + "fd=%d idx=%d\n", + fd, idx); socket_fds_idx[fd] = idx; /* This builtin issues a full memory barrier. */ __sync_synchronize(); @@ -1543,6 +1640,9 @@ static void set_socket_info_index(int fd, int idx) static void reset_socket_info_index(int fd) { + SWRAP_LOG(SWRAP_LOG_TRACE, + "fd=%d idx=%d\n", + fd, -1); set_socket_info_index(fd, -1); } @@ -1678,7 +1778,7 @@ static int convert_un_in(const struct sockaddr_un *un, struct sockaddr *in, sock memset(in2, 0, sizeof(*in2)); in2->sin_family = AF_INET; - in2->sin_addr.s_addr = htonl((127<<24) | iface); + in2->sin_addr.s_addr = htonl(swrap_ipv4_iface(iface)); in2->sin_port = htons(prt); *len = sizeof(*in2); @@ -1731,6 +1831,8 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i char u_type = '\0'; char b_type = '\0'; char a_type = '\0'; + const unsigned int sw_net_addr = swrap_ipv4_net(); + const unsigned int sw_bcast_addr = swrap_ipv4_bcast(); switch (si->type) { case SOCK_STREAM: @@ -1753,13 +1855,18 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i is_bcast = 2; type = a_type; iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { - /* 127.255.255.255 only udp */ + } else if (b_type && addr == sw_bcast_addr) { + /* + * 127.255.255.255 + * or + * 10.255.255.255 + * only udp + */ is_bcast = 1; type = b_type; iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { - /* 127.0.0.X */ + } else if ((addr & 0xFFFFFF00) == sw_net_addr) { + /* 127.0.0.X or 10.53.57.X */ is_bcast = 0; type = u_type; iface = (addr & 0x000000FF); @@ -1863,6 +1970,8 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in char d_type = '\0'; char b_type = '\0'; char a_type = '\0'; + const unsigned int sw_net_addr = swrap_ipv4_net(); + const unsigned int sw_bcast_addr = swrap_ipv4_bcast(); prt = ntohs(in->sin_port); @@ -1893,12 +2002,12 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in is_bcast = 2; type = a_type; iface = socket_wrapper_default_iface(); - } else if (b_type && addr == 0x7FFFFFFF) { + } else if (b_type && addr == sw_bcast_addr) { /* 127.255.255.255 only udp */ is_bcast = 1; type = b_type; iface = socket_wrapper_default_iface(); - } else if ((addr & 0xFFFFFF00) == 0x7F000000) { + } else if ((addr & 0xFFFFFF00) == sw_net_addr) { /* 127.0.0.X */ is_bcast = 0; type = u_type; @@ -1916,8 +2025,7 @@ static int convert_in_un_alloc(struct socket_info *si, const struct sockaddr *in ZERO_STRUCT(bind_in); bind_in.sin_family = in->sin_family; bind_in.sin_port = in->sin_port; - bind_in.sin_addr.s_addr = htonl(0x7F000000 | iface); - + bind_in.sin_addr.s_addr = htonl(swrap_ipv4_iface(iface)); si->bindname.sa_socklen = blen; memcpy(&si->bindname.sa.in, &bind_in, blen); } @@ -2455,6 +2563,7 @@ static const char *swrap_pcap_init_file(void) if (strncmp(s, "./", 2) == 0) { s += 2; } + SWRAP_LOG(SWRAP_LOG_TRACE, "SOCKET_WRAPPER_PCAP_FILE: %s", s); return s; } @@ -3140,7 +3249,15 @@ static int swrap_socket(int family, int type, int protocol) case AF_PACKET: #endif /* AF_PACKET */ case AF_UNIX: - return libc_socket(family, type, protocol); + fd = libc_socket(family, type, protocol); + if (fd != -1) { + /* Check if we have a stale fd and remove it */ + swrap_remove_stale(fd); + SWRAP_LOG(SWRAP_LOG_TRACE, + "Unix socket fd=%d", + fd); + } + return fd; default: errno = EAFNOSUPPORT; return -1; @@ -3384,6 +3501,9 @@ static int swrap_accept(int s, fd = ret; + /* Check if we have a stale fd and remove it */ + swrap_remove_stale(fd); + SWRAP_LOCK_SI(parent_si); ret = sockaddr_convert_from_un(parent_si, @@ -3536,8 +3656,8 @@ static int swrap_auto_bind(int fd, struct socket_info *si, int family) memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; - in.sin_addr.s_addr = htonl(127<<24 | - socket_wrapper_default_iface()); + in.sin_addr.s_addr = htonl(swrap_ipv4_iface( + socket_wrapper_default_iface())); si->myname = (struct swrap_address) { .sa_socklen = sizeof(in), @@ -3666,6 +3786,9 @@ static int swrap_connect(int s, const struct sockaddr *serv_addr, } if (si->family != serv_addr->sa_family) { + SWRAP_LOG(SWRAP_LOG_ERROR, + "called for fd=%d (family=%d) called with invalid family=%d\n", + s, si->family, serv_addr->sa_family); errno = EINVAL; ret = -1; goto done; @@ -6076,6 +6199,7 @@ static int swrap_close(int fd) return libc_close(fd); } + SWRAP_LOG(SWRAP_LOG_TRACE, "Close wrapper for fd=%d", fd); reset_socket_info_index(fd); si = swrap_get_socket_info(si_index); @@ -6410,3 +6534,54 @@ void swrap_destructor(void) dlclose(swrap.libc.socket_handle); } } + +#if defined(HAVE__SOCKET) && defined(HAVE__CLOSE) +/* + * On FreeBSD 12 (and maybe other platforms) + * system libraries like libresolv prefix there + * syscalls with '_' in order to always use + * the symbols from libc. + * + * In the interaction with resolv_wrapper, + * we need to inject socket wrapper into libresolv, + * which means we need to private all socket + * related syscalls also with the '_' prefix. + * + * This is tested in Samba's 'make test', + * there we noticed that providing '_read' + * and '_open' would cause errors, which + * means we skip '_read', '_write' and + * all non socket related calls without + * further analyzing the problem. + */ +#define SWRAP_SYMBOL_ALIAS(__sym, __aliassym) \ + extern typeof(__sym) __aliassym __attribute__ ((alias(#__sym))) + +#ifdef HAVE_ACCEPT4 +SWRAP_SYMBOL_ALIAS(accept4, _accept4); +#endif +SWRAP_SYMBOL_ALIAS(accept, _accept); +SWRAP_SYMBOL_ALIAS(bind, _bind); +SWRAP_SYMBOL_ALIAS(close, _close); +SWRAP_SYMBOL_ALIAS(connect, _connect); +SWRAP_SYMBOL_ALIAS(dup, _dup); +SWRAP_SYMBOL_ALIAS(dup2, _dup2); +SWRAP_SYMBOL_ALIAS(fcntl, _fcntl); +SWRAP_SYMBOL_ALIAS(getpeername, _getpeername); +SWRAP_SYMBOL_ALIAS(getsockname, _getsockname); +SWRAP_SYMBOL_ALIAS(getsockopt, _getsockopt); +SWRAP_SYMBOL_ALIAS(ioctl, _ioctl); +SWRAP_SYMBOL_ALIAS(listen, _listen); +SWRAP_SYMBOL_ALIAS(readv, _readv); +SWRAP_SYMBOL_ALIAS(recv, _recv); +SWRAP_SYMBOL_ALIAS(recvfrom, _recvfrom); +SWRAP_SYMBOL_ALIAS(recvmsg, _recvmsg); +SWRAP_SYMBOL_ALIAS(send, _send); +SWRAP_SYMBOL_ALIAS(sendmsg, _sendmsg); +SWRAP_SYMBOL_ALIAS(sendto, _sendto); +SWRAP_SYMBOL_ALIAS(setsockopt, _setsockopt); +SWRAP_SYMBOL_ALIAS(socket, _socket); +SWRAP_SYMBOL_ALIAS(socketpair, _socketpair); +SWRAP_SYMBOL_ALIAS(writev, _writev); + +#endif /* SOCKET_WRAPPER_EXPORT_UNDERSCORE_SYMBOLS */ diff --git a/third_party/socket_wrapper/wscript b/third_party/socket_wrapper/wscript index 68972da0794..a9272c783a4 100644 --- a/third_party/socket_wrapper/wscript +++ b/third_party/socket_wrapper/wscript @@ -2,7 +2,7 @@ import os -VERSION="1.2.3" +VERSION="1.2.4" def configure(conf): if conf.CHECK_SOCKET_WRAPPER(): @@ -71,6 +71,14 @@ def configure(conf): 'int eventfd(unsigned int count, int flags)', define='HAVE_EVENTFD_UNSIGNED_INT', headers='sys/eventfd.h') + # FreeBSD exports each syscall also with '_' as prefix + # and these symbols are used if called by system libraries itself. + # That means socket_wrapper needs to implement these too + # in order to inject itself into system libraries, + # we just check for _socket and _close and assume the rest + # is also there... + conf.CHECK_FUNCS('_socket _close') + # Create full path to socket_wrapper blddir = os.path.realpath(conf.bldnode.abspath()) libsocket_wrapper_so_path = blddir + '/default/third_party/socket_wrapper/libsocket-wrapper.so' |