1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

third_party: Update socket_wrapper to version 1.3.3

This fixes a deadlock abort() when SOCKET_WRAPPER_KEEP_PCAP=1
is used.

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Wed Mar 17 23:53:04 UTC 2021 on sn-devel-184
This commit is contained in:
Stefan Metzmacher 2021-02-17 12:57:01 +01:00
parent 8aef8992a8
commit 10c198827d
4 changed files with 197 additions and 54 deletions

View File

@ -24,7 +24,7 @@ Build.BuildContext.CHECK_CMOCKA = CHECK_CMOCKA
@conf
def CHECK_SOCKET_WRAPPER(conf):
return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.3.2')
return conf.CHECK_BUNDLED_SYSTEM_PKG('socket_wrapper', minversion='1.3.3')
Build.BuildContext.CHECK_SOCKET_WRAPPER = CHECK_SOCKET_WRAPPER
@conf

View File

@ -2,8 +2,8 @@
* BSD 3-Clause License
*
* Copyright (c) 2005-2008, Jelmer Vernooij <jelmer@samba.org>
* Copyright (c) 2006-2018, Stefan Metzmacher <metze@samba.org>
* Copyright (c) 2013-2018, Andreas Schneider <asn@samba.org>
* Copyright (c) 2006-2021, Stefan Metzmacher <metze@samba.org>
* Copyright (c) 2013-2021, Andreas Schneider <asn@samba.org>
* Copyright (c) 2014-2017, Michael Adam <obnox@samba.org>
* Copyright (c) 2016-2018, Anoop C S <anoopcs@redhat.com>
* All rights reserved.
@ -86,6 +86,8 @@
#endif
#include <pthread.h>
#include "socket_wrapper.h"
enum swrap_dbglvl_e {
SWRAP_LOG_ERROR = 0,
SWRAP_LOG_WARN,
@ -370,7 +372,7 @@ static pthread_mutex_t autobind_start_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Mutex to guard the initialization of array of socket_info structures */
static pthread_mutex_t sockets_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Mutex to guard the socket reset in swrap_close() and swrap_remove_stale() */
/* Mutex to guard the socket reset in swrap_remove_wrapper() */
static pthread_mutex_t socket_reset_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Mutex to synchronize access to first free index in socket_info array */
@ -392,8 +394,6 @@ static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Function prototypes */
bool socket_wrapper_enabled(void);
#if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT)
/* xlC and other oldschool compilers support (only) this */
#pragma init (swrap_constructor)
@ -492,6 +492,9 @@ typedef int (*__libc_bind)(int sockfd,
const struct sockaddr *addr,
socklen_t addrlen);
typedef int (*__libc_close)(int fd);
#ifdef HAVE___CLOSE_NOCANCEL
typedef int (*__libc___close_nocancel)(int fd);
#endif
typedef int (*__libc_connect)(int sockfd,
const struct sockaddr *addr,
socklen_t addrlen);
@ -572,6 +575,9 @@ struct swrap_libc_symbols {
#endif
SWRAP_SYMBOL_ENTRY(bind);
SWRAP_SYMBOL_ENTRY(close);
#ifdef HAVE___CLOSE_NOCANCEL
SWRAP_SYMBOL_ENTRY(__close_nocancel);
#endif
SWRAP_SYMBOL_ENTRY(connect);
SWRAP_SYMBOL_ENTRY(dup);
SWRAP_SYMBOL_ENTRY(dup2);
@ -851,6 +857,15 @@ static int libc_close(int fd)
return swrap.libc.symbols._libc_close.f(fd);
}
#ifdef HAVE___CLOSE_NOCANCEL
static int libc___close_nocancel(int fd)
{
swrap_bind_symbol_all();
return swrap.libc.symbols._libc___close_nocancel.f(fd);
}
#endif /* HAVE___CLOSE_NOCANCEL */
static int libc_connect(int sockfd,
const struct sockaddr *addr,
socklen_t addrlen)
@ -1199,6 +1214,9 @@ static void __swrap_bind_symbol_all_once(void)
#endif
swrap_bind_symbol_libsocket(bind);
swrap_bind_symbol_libc(close);
#ifdef HAVE___CLOSE_NOCANCEL
swrap_bind_symbol_libc(__close_nocancel);
#endif
swrap_bind_symbol_libsocket(connect);
swrap_bind_symbol_libc(dup);
swrap_bind_symbol_libc(dup2);
@ -2027,6 +2045,13 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
type = u_type;
iface = (addr & 0x000000FF);
} else {
char str[256] = {0,};
inet_ntop(inaddr->sa_family,
&in->sin_addr,
str, sizeof(str));
SWRAP_LOG(SWRAP_LOG_WARN,
"str[%s] prt[%u]",
str, (unsigned)prt);
errno = ENETUNREACH;
return -1;
}
@ -2062,6 +2087,13 @@ static int convert_in_un_remote(struct socket_info *si, const struct sockaddr *i
if (IN6_ARE_ADDR_EQUAL(&cmp1, &cmp2)) {
iface = in->sin6_addr.s6_addr[15];
} else {
char str[256] = {0,};
inet_ntop(inaddr->sa_family,
&in->sin6_addr,
str, sizeof(str));
SWRAP_LOG(SWRAP_LOG_WARN,
"str[%s] prt[%u]",
str, (unsigned)prt);
errno = ENETUNREACH;
return -1;
}
@ -2390,46 +2422,7 @@ static bool check_addr_port_in_use(const struct sockaddr *sa, socklen_t len)
}
#endif
static void swrap_remove_stale(int fd)
{
struct socket_info *si;
int si_index;
SWRAP_LOG(SWRAP_LOG_TRACE, "remove stale wrapper for %d", fd);
swrap_mutex_lock(&socket_reset_mutex);
si_index = find_socket_info_index(fd);
if (si_index == -1) {
swrap_mutex_unlock(&socket_reset_mutex);
return;
}
reset_socket_info_index(fd);
si = swrap_get_socket_info(si_index);
swrap_mutex_lock(&first_free_mutex);
SWRAP_LOCK_SI(si);
swrap_dec_refcount(si);
if (swrap_get_refcount(si) > 0) {
goto out;
}
if (si->un_addr.sun_path[0] != '\0') {
unlink(si->un_addr.sun_path);
}
swrap_set_next_free(si, first_free);
first_free = si_index;
out:
SWRAP_UNLOCK_SI(si);
swrap_mutex_unlock(&first_free_mutex);
swrap_mutex_unlock(&socket_reset_mutex);
}
static void swrap_remove_stale(int fd);
static int sockaddr_convert_to_un(struct socket_info *si,
const struct sockaddr *in_addr,
@ -2990,7 +2983,7 @@ static int swrap_pcap_get_fd(const char *fname)
file_hdr.frame_max_len = SWRAP_FRAME_LENGTH_MAX;
file_hdr.link_type = 0x0065; /* 101 RAW IP */
if (write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
if (libc_write(fd, &file_hdr, sizeof(file_hdr)) != sizeof(file_hdr)) {
libc_close(fd);
fd = -1;
}
@ -3325,7 +3318,7 @@ static void swrap_pcap_dump_packet(struct socket_info *si,
fd = swrap_pcap_get_fd(file_name);
if (fd != -1) {
if (write(fd, packet, packet_len) != (ssize_t)packet_len) {
if (libc_write(fd, packet, packet_len) != (ssize_t)packet_len) {
free(packet);
goto done;
}
@ -5532,7 +5525,7 @@ static int swrap_sendmsg_unix_scm_rights(const struct cmsghdr *cmsg,
return -1;
}
sret = write(pipefd[1], &info, sizeof(info));
sret = libc_write(pipefd[1], &info, sizeof(info));
if (sret != sizeof(info)) {
int saved_errno = errno;
if (sret != -1) {
@ -7403,10 +7396,13 @@ ssize_t writev(int s, const struct iovec *vector, int count)
* CLOSE
***************************/
static int swrap_close(int fd)
static int swrap_remove_wrapper(const char *__func_name,
int (*__close_fd_fn)(int fd),
int fd)
{
struct socket_info *si = NULL;
int si_index;
int ret_errno = errno;
int ret;
swrap_mutex_lock(&socket_reset_mutex);
@ -7414,10 +7410,10 @@ static int swrap_close(int fd)
si_index = find_socket_info_index(fd);
if (si_index == -1) {
swrap_mutex_unlock(&socket_reset_mutex);
return libc_close(fd);
return __close_fd_fn(fd);
}
SWRAP_LOG(SWRAP_LOG_TRACE, "Close wrapper for fd=%d", fd);
swrap_log(SWRAP_LOG_TRACE, __func_name, "Remove wrapper for fd=%d", fd);
reset_socket_info_index(fd);
si = swrap_get_socket_info(si_index);
@ -7425,7 +7421,10 @@ static int swrap_close(int fd)
swrap_mutex_lock(&first_free_mutex);
SWRAP_LOCK_SI(si);
ret = libc_close(fd);
ret = __close_fd_fn(fd);
if (ret == -1) {
ret_errno = errno;
}
swrap_dec_refcount(si);
@ -7460,14 +7459,68 @@ out:
swrap_mutex_unlock(&first_free_mutex);
swrap_mutex_unlock(&socket_reset_mutex);
errno = ret_errno;
return ret;
}
static int swrap_noop_close(int fd)
{
(void)fd; /* unused */
return 0;
}
static void swrap_remove_stale(int fd)
{
swrap_remove_wrapper(__func__, swrap_noop_close, fd);
}
/*
* This allows socket_wrapper aware applications to
* indicate that the given fd does not belong to
* an inet socket.
*
* We already overload a lot of unrelated functions
* like eventfd(), timerfd_create(), ... in order to
* call swrap_remove_stale() on the returned fd, but
* we'll never be able to handle all possible syscalls.
*
* socket_wrapper_indicate_no_inet_fd() gives them a way
* to do the same.
*
* We don't export swrap_remove_stale() in order to
* make it easier to analyze SOCKET_WRAPPER_DEBUGLEVEL=3
* log files.
*/
void socket_wrapper_indicate_no_inet_fd(int fd)
{
swrap_remove_wrapper(__func__, swrap_noop_close, fd);
}
static int swrap_close(int fd)
{
return swrap_remove_wrapper(__func__, libc_close, fd);
}
int close(int fd)
{
return swrap_close(fd);
}
#ifdef HAVE___CLOSE_NOCANCEL
static int swrap___close_nocancel(int fd)
{
return swrap_remove_wrapper(__func__, libc___close_nocancel, fd);
}
int __close_nocancel(int fd);
int __close_nocancel(int fd)
{
return swrap___close_nocancel(fd);
}
#endif /* HAVE___CLOSE_NOCANCEL */
/****************************
* DUP
***************************/

View File

@ -0,0 +1,89 @@
/*
* BSD 3-Clause License
*
* Copyright (c) 2005-2008, Jelmer Vernooij <jelmer@samba.org>
* Copyright (c) 2006-2021, Stefan Metzmacher <metze@samba.org>
* Copyright (c) 2013-2021, Andreas Schneider <asn@samba.org>
* Copyright (c) 2014-2017, Michael Adam <obnox@samba.org>
* Copyright (c) 2016-2018, Anoop C S <anoopcs@redhat.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef __SOCKET_WRAPPER_H__
#define __SOCKET_WRAPPER_H__ 1
#include <stdbool.h>
/*
Socket wrapper advanced helpers.
Applications with the need to alter their behaviour when
socket wrapper is active, can link use these functions.
By default it's required for applications to use any of these
functions as libsocket_wrapper.so is injected at runtime via
LD_PRELOAD.
Applications using these functions should link against
libsocket_wrapper_noop.so by using -lsocket_wrapper_noop,
or implement their own noop stubs.
*/
/*
* This returns true when socket wrapper is actively in use.
*/
bool socket_wrapper_enabled(void);
/*
* This allows socket_wrapper aware applications to
* indicate that the given fd does not belong to
* an inet socket.
*
* socket_wrapper may not be able to intercept the __close_nocancel()
* syscall made from within libc.so. As result it's possible
* that the in memory meta date of socket_wrapper references
* stale file descriptors, which are already reused for unrelated
* kernel objects, e.g. files, directories, ...
*
* Socket wrapper already intercepts a lot of unrelated
* functions like eventfd(), timerfd_create(), ... in order
* to remove stale meta data for the returned fd, but
* it will never be able to handle all possible syscalls.
*
* socket_wrapper_indicate_no_inet_fd() gives applications a way
* to do the same, explicitly without waiting for new syscalls to
* be added to libsocket_wrapper.so.
*
* This is a no-op if socket_wrapper is not in use or
* if the there is no in memory meta data for the given fd.
*/
void socket_wrapper_indicate_no_inet_fd(int fd);
#endif /* __SOCKET_WRAPPER_H__ */

View File

@ -2,7 +2,7 @@
import os
VERSION="1.3.2"
VERSION="1.3.3"
def configure(conf):
if conf.CHECK_SOCKET_WRAPPER():
@ -53,6 +53,7 @@ def configure(conf):
conf.CHECK_FUNCS('bindresvport')
conf.CHECK_FUNCS('pledge')
conf.CHECK_FUNCS('accept4')
conf.CHECK_FUNCS('__close_nocancel')
conf.CHECK_FUNCS_IN('bind',
'socket',