2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
17 * Copyright (c) 2005-2008 Jelmer Vernooij <jelmer@samba.org>
18 * Copyright (C) 2006-2014 Stefan Metzmacher <metze@samba.org>
19 * Copyright (C) 2013-2014 Andreas Schneider <asn@samba.org>
21 * All rights reserved.
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
27 * 1. Redistributions of source code must retain the above copyright
28 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
34 * 3. Neither the name of the author nor the names of its contributors
35 * may be used to endorse or promote products derived from this software
36 * without specific prior written permission.
38 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
39 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
42 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 Socket wrapper library. Passes all socket communication over
54 unix domain sockets if the environment variable SOCKET_WRAPPER_DIR
66 #include <vcl/vcom_socket_wrapper.h>
78 /* Macros for accessing mutexes */
79 #define SWRAP_LOCK(m) do { \
80 pthread_mutex_lock(&(m ## _mutex)); \
83 #define SWRAP_UNLOCK(m) do { \
84 pthread_mutex_unlock(&(m ## _mutex)); \
87 /* Add new global locks here please */
88 #define SWRAP_LOCK_ALL \
89 SWRAP_LOCK(libc_symbol_binding); \
91 #define SWRAP_UNLOCK_ALL \
92 SWRAP_UNLOCK(libc_symbol_binding); \
96 /* The mutex for accessing the global libc.symbols */
97 static pthread_mutex_t libc_symbol_binding_mutex = PTHREAD_MUTEX_INITIALIZER;
99 /* Function prototypes */
102 #define SWRAP_LOG(...)
104 static unsigned int swrap_log_lvl = SWRAP_LOG_WARN;
107 swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
108 const char *format, ...)
109 PRINTF_ATTRIBUTE (3, 4);
110 #define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
113 swrap_log (enum swrap_dbglvl_e dbglvl,
114 const char *func, const char *format, ...)
119 va_start (va, format);
120 vsnprintf (buffer, sizeof (buffer), format, va);
123 if (dbglvl <= swrap_log_lvl)
127 case SWRAP_LOG_ERROR:
129 "SWRAP_ERROR(%d) - %s: %s\n",
130 (int) getpid (), func, buffer);
134 "SWRAP_WARN(%d) - %s: %s\n",
135 (int) getpid (), func, buffer);
137 case SWRAP_LOG_DEBUG:
139 "SWRAP_DEBUG(%d) - %s: %s\n",
140 (int) getpid (), func, buffer);
142 case SWRAP_LOG_TRACE:
144 "SWRAP_TRACE(%d) - %s: %s\n",
145 (int) getpid (), func, buffer);
153 /*********************************************************
154 * SWRAP LOADING LIBC FUNCTIONS
155 *********************************************************/
158 typedef int (*__libc_accept4) (int sockfd,
159 struct sockaddr * addr,
160 socklen_t * addrlen, int flags);
162 typedef int (*__libc_accept) (int sockfd,
163 struct sockaddr * addr, socklen_t * addrlen);
165 typedef int (*__libc_bind) (int sockfd,
166 const struct sockaddr * addr, socklen_t addrlen);
167 typedef int (*__libc_close) (int fd);
168 typedef int (*__libc_connect) (int sockfd,
169 const struct sockaddr * addr,
173 /* TBD: dup and dup2 to be implemented later */
174 typedef int (*__libc_dup) (int fd);
175 typedef int (*__libc_dup2) (int oldfd, int newfd);
178 typedef int (*__libc_fcntl) (int fd, int cmd, ...);
179 typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
181 typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
184 typedef int (*__libc_eventfd) (int count, int flags);
186 typedef int (*__libc_getpeername) (int sockfd,
187 struct sockaddr * addr,
188 socklen_t * addrlen);
189 typedef int (*__libc_getsockname) (int sockfd,
190 struct sockaddr * addr,
191 socklen_t * addrlen);
192 typedef int (*__libc_getsockopt) (int sockfd,
195 void *optval, socklen_t * optlen);
196 typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
197 typedef int (*__libc_listen) (int sockfd, int backlog);
198 typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
200 typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
201 #endif /* HAVE_OPEN64 */
202 typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
203 typedef int (*__libc_pipe) (int pipefd[2]);
204 typedef int (*__libc_read) (int fd, void *buf, size_t count);
205 typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov,
207 typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
208 typedef int (*__libc_recvfrom) (int sockfd,
212 struct sockaddr * src_addr,
213 socklen_t * addrlen);
214 typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg,
216 typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
218 typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
220 typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
221 int flags, const struct sockaddr * dst_addr,
223 typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
224 const void *optval, socklen_t optlen);
226 typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
228 typedef int (*__libc_socket) (int domain, int type, int protocol);
229 typedef int (*__libc_socketpair) (int domain, int type, int protocol,
231 #ifdef HAVE_TIMERFD_CREATE
232 typedef int (*__libc_timerfd_create) (int clockid, int flags);
234 typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
235 typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
238 typedef int (*__libc_shutdown) (int fd, int how);
240 typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
241 fd_set * __restrict __writefds,
242 fd_set * __restrict __exceptfds,
243 struct timeval * __restrict __timeout);
246 typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
247 fd_set * __restrict __writefds,
248 fd_set * __restrict __exceptfds,
249 const struct timespec * __restrict __timeout,
250 const __sigset_t * __restrict __sigmask);
253 typedef int (*__libc_epoll_create) (int __size);
255 typedef int (*__libc_epoll_create1) (int __flags);
257 typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
258 struct epoll_event * __event);
260 typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
261 int __maxevents, int __timeout);
263 typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
264 int __maxevents, int __timeout,
265 const __sigset_t * __ss);
267 typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
271 typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
272 const struct timespec * __timeout,
273 const __sigset_t * __ss);
277 #define SWRAP_SYMBOL_ENTRY(i) \
283 struct swrap_libc_symbols
286 SWRAP_SYMBOL_ENTRY (accept4);
288 SWRAP_SYMBOL_ENTRY (accept);
290 SWRAP_SYMBOL_ENTRY (bind);
291 SWRAP_SYMBOL_ENTRY (close);
292 SWRAP_SYMBOL_ENTRY (connect);
294 /* TBD: dup and dup2 to be implemented later */
295 SWRAP_SYMBOL_ENTRY (dup);
296 SWRAP_SYMBOL_ENTRY (dup2);
298 SWRAP_SYMBOL_ENTRY (fcntl);
299 SWRAP_SYMBOL_ENTRY (fopen);
301 SWRAP_SYMBOL_ENTRY (fopen64);
304 SWRAP_SYMBOL_ENTRY (eventfd);
306 SWRAP_SYMBOL_ENTRY (getpeername);
307 SWRAP_SYMBOL_ENTRY (getsockname);
308 SWRAP_SYMBOL_ENTRY (getsockopt);
309 SWRAP_SYMBOL_ENTRY (ioctl);
310 SWRAP_SYMBOL_ENTRY (listen);
311 SWRAP_SYMBOL_ENTRY (open);
313 SWRAP_SYMBOL_ENTRY (open64);
315 SWRAP_SYMBOL_ENTRY (openat);
316 SWRAP_SYMBOL_ENTRY (pipe);
317 SWRAP_SYMBOL_ENTRY (read);
318 SWRAP_SYMBOL_ENTRY (readv);
319 SWRAP_SYMBOL_ENTRY (recv);
320 SWRAP_SYMBOL_ENTRY (recvfrom);
321 SWRAP_SYMBOL_ENTRY (recvmsg);
322 SWRAP_SYMBOL_ENTRY (send);
323 SWRAP_SYMBOL_ENTRY (sendmsg);
324 SWRAP_SYMBOL_ENTRY (sendto);
325 SWRAP_SYMBOL_ENTRY (setsockopt);
327 SWRAP_SYMBOL_ENTRY (signalfd);
329 SWRAP_SYMBOL_ENTRY (socket);
330 SWRAP_SYMBOL_ENTRY (socketpair);
331 #ifdef HAVE_TIMERFD_CREATE
332 SWRAP_SYMBOL_ENTRY (timerfd_create);
334 SWRAP_SYMBOL_ENTRY (write);
335 SWRAP_SYMBOL_ENTRY (writev);
337 SWRAP_SYMBOL_ENTRY (shutdown);
338 SWRAP_SYMBOL_ENTRY (select);
340 SWRAP_SYMBOL_ENTRY (pselect);
342 SWRAP_SYMBOL_ENTRY (epoll_create);
343 SWRAP_SYMBOL_ENTRY (epoll_create1);
344 SWRAP_SYMBOL_ENTRY (epoll_ctl);
345 SWRAP_SYMBOL_ENTRY (epoll_wait);
346 SWRAP_SYMBOL_ENTRY (epoll_pwait);
347 SWRAP_SYMBOL_ENTRY (poll);
349 SWRAP_SYMBOL_ENTRY (ppoll);
359 struct swrap_libc_symbols symbols;
363 static struct swrap swrap;
365 #define LIBC_NAME "libc.so"
374 swrap_str_lib (enum swrap_lib lib)
382 /* Compiler would warn us about unhandled enum value if we get here */
388 swrap_load_lib_handle (enum swrap_lib lib)
390 int flags = RTLD_LAZY;
395 flags |= RTLD_DEEPBIND;
401 handle = swrap.libc.handle;
405 handle = dlopen (LIBC_SO, flags);
407 swrap.libc.handle = handle;
412 for (i = 10; i >= 0; i--)
414 char soname[256] = { 0 };
416 snprintf (soname, sizeof (soname), "libc.so.%d", i);
417 handle = dlopen (soname, flags);
424 swrap.libc.handle = handle;
431 SWRAP_LOG (SWRAP_LOG_ERROR,
432 "Failed to dlopen library: %s\n", dlerror ());
440 _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
445 handle = swrap_load_lib_handle (lib);
447 func = dlsym (handle, fn_name);
450 SWRAP_LOG (SWRAP_LOG_ERROR,
451 "Failed to find %s: %s\n", fn_name, dlerror ());
455 SWRAP_LOG (SWRAP_LOG_TRACE,
456 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
461 #define swrap_bind_symbol_libc(sym_name) \
462 SWRAP_LOCK(libc_symbol_binding); \
463 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
464 swrap.libc.symbols._libc_##sym_name.obj = \
465 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
467 SWRAP_UNLOCK(libc_symbol_binding)
472 * Functions especially from libc need to be loaded individually, you can't load
473 * all at once or gdb will segfault at startup. The same applies to valgrind and
474 * has probably something todo with with the linker.
475 * So we need load each function at the point it is called the first time.
479 libc_accept4 (int sockfd,
480 struct sockaddr *addr, socklen_t * addrlen, int flags)
482 swrap_bind_symbol_libc (accept4);
484 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
487 #else /* HAVE_ACCEPT4 */
490 libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
492 swrap_bind_symbol_libc (accept);
494 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
496 #endif /* HAVE_ACCEPT4 */
499 libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
501 swrap_bind_symbol_libc (bind);
503 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
509 swrap_bind_symbol_libc (close);
511 return swrap.libc.symbols._libc_close.f (fd);
515 libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
517 swrap_bind_symbol_libc (connect);
519 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
523 /* TBD: dup and dup2 to be implemented later */
527 swrap_bind_symbol_libc (dup);
529 return swrap.libc.symbols._libc_dup.f (fd);
533 libc_dup2 (int oldfd, int newfd)
535 swrap_bind_symbol_libc (dup2);
537 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
543 libc_eventfd (int count, int flags)
545 swrap_bind_symbol_libc (eventfd);
547 return swrap.libc.symbols._libc_eventfd.f (count, flags);
551 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
552 libc_vfcntl (int fd, int cmd, va_list ap)
558 swrap_bind_symbol_libc (fcntl);
560 for (i = 0; i < 4; i++)
562 args[i] = va_arg (ap, long int);
565 rc = swrap.libc.symbols._libc_fcntl.f (fd,
567 args[0], args[1], args[2], args[3]);
572 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
573 libc_vioctl (int fd, int cmd, va_list ap)
579 swrap_bind_symbol_libc (ioctl);
581 for (i = 0; i < 4; i++)
583 args[i] = va_arg (ap, long int);
586 rc = swrap.libc.symbols._libc_ioctl.f (fd,
588 args[0], args[1], args[2], args[3]);
594 libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
596 swrap_bind_symbol_libc (getpeername);
598 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
602 libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
604 swrap_bind_symbol_libc (getsockname);
606 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
610 libc_getsockopt (int sockfd,
611 int level, int optname, void *optval, socklen_t * optlen)
613 swrap_bind_symbol_libc (getsockopt);
615 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
617 optname, optval, optlen);
621 libc_listen (int sockfd, int backlog)
623 swrap_bind_symbol_libc (listen);
625 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
629 libc_read (int fd, void *buf, size_t count)
631 swrap_bind_symbol_libc (read);
633 return swrap.libc.symbols._libc_read.f (fd, buf, count);
637 libc_readv (int fd, const struct iovec * iov, int iovcnt)
639 swrap_bind_symbol_libc (readv);
641 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
645 libc_recv (int sockfd, void *buf, size_t len, int flags)
647 swrap_bind_symbol_libc (recv);
649 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
653 libc_recvfrom (int sockfd,
656 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
658 swrap_bind_symbol_libc (recvfrom);
660 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
662 len, flags, src_addr, addrlen);
666 libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
668 swrap_bind_symbol_libc (recvmsg);
670 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
674 libc_send (int sockfd, const void *buf, size_t len, int flags)
676 swrap_bind_symbol_libc (send);
678 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
682 libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
684 swrap_bind_symbol_libc (sendmsg);
686 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
690 libc_sendto (int sockfd,
693 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
695 swrap_bind_symbol_libc (sendto);
697 return swrap.libc.symbols._libc_sendto.f (sockfd,
699 len, flags, dst_addr, addrlen);
703 libc_setsockopt (int sockfd,
704 int level, int optname, const void *optval, socklen_t optlen)
706 swrap_bind_symbol_libc (setsockopt);
708 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
710 optname, optval, optlen);
714 libc_socket (int domain, int type, int protocol)
716 swrap_bind_symbol_libc (socket);
718 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
722 libc_socketpair (int domain, int type, int protocol, int sv[2])
724 swrap_bind_symbol_libc (socketpair);
726 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
730 libc_write (int fd, const void *buf, size_t count)
732 swrap_bind_symbol_libc (write);
734 return swrap.libc.symbols._libc_write.f (fd, buf, count);
738 libc_writev (int fd, const struct iovec * iov, int iovcnt)
740 swrap_bind_symbol_libc (writev);
742 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
746 libc_shutdown (int fd, int how)
748 swrap_bind_symbol_libc (shutdown);
750 return swrap.libc.symbols._libc_shutdown.f (fd, how);
754 libc_select (int __nfds, fd_set * __restrict __readfds,
755 fd_set * __restrict __writefds,
756 fd_set * __restrict __exceptfds,
757 struct timeval *__restrict __timeout)
759 swrap_bind_symbol_libc (select);
761 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
763 __exceptfds, __timeout);
768 libc_pselect (int __nfds, fd_set * __restrict __readfds,
769 fd_set * __restrict __writefds,
770 fd_set * __restrict __exceptfds,
771 const struct timespec *__restrict __timeout,
772 const __sigset_t * __restrict __sigmask)
774 swrap_bind_symbol_libc (pselect);
776 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
779 __timeout, __sigmask);
784 libc_epoll_create (int __size)
786 swrap_bind_symbol_libc (epoll_create);
788 return swrap.libc.symbols._libc_epoll_create.f (__size);
792 libc_epoll_create1 (int __flags)
794 swrap_bind_symbol_libc (epoll_create1);
796 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
800 libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
802 swrap_bind_symbol_libc (epoll_ctl);
804 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
808 libc_epoll_wait (int __epfd, struct epoll_event *__events,
809 int __maxevents, int __timeout)
811 swrap_bind_symbol_libc (epoll_wait);
813 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
814 __maxevents, __timeout);
818 libc_epoll_pwait (int __epfd, struct epoll_event *__events,
819 int __maxevents, int __timeout, const __sigset_t * __ss)
821 swrap_bind_symbol_libc (epoll_pwait);
823 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
824 __maxevents, __timeout,
829 libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
831 swrap_bind_symbol_libc (poll);
833 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
838 libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
839 const struct timespec *__timeout, const __sigset_t * __ss)
841 swrap_bind_symbol_libc (ppoll);
843 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
848 swrap_thread_prepare (void)
854 swrap_thread_parent (void)
860 swrap_thread_child (void)
865 /****************************
867 ***************************/
869 swrap_constructor (void)
872 * If we hold a lock and the application forks, then the child
873 * is not able to unlock the mutex and we are in a deadlock.
874 * This should prevent such deadlocks.
876 pthread_atfork (&swrap_thread_prepare,
877 &swrap_thread_parent, &swrap_thread_child);
880 /****************************
882 ***************************/
885 * This function is called when the library is unloaded and makes sure that
886 * sockets get closed and the unix file for the socket are unlinked.
889 swrap_destructor (void)
891 if (swrap.libc.handle != NULL)
893 dlclose (swrap.libc.handle);
895 if (swrap.libc.socket_handle)
897 dlclose (swrap.libc.socket_handle);
902 * fd.io coding-style-patch-verification: ON
905 * eval: (c-set-style "gnu")