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 <libvcl-ldpreload/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(...)
105 swrap_log (enum swrap_dbglvl_e dbglvl, const char *func,
106 const char *format, ...)
107 PRINTF_ATTRIBUTE (3, 4);
108 #define SWRAP_LOG(dbglvl, ...) swrap_log((dbglvl), __func__, __VA_ARGS__)
111 swrap_log (enum swrap_dbglvl_e dbglvl,
112 const char *func, const char *format, ...)
116 unsigned int lvl = SWRAP_LOG_WARN;
118 va_start (va, format);
119 vsnprintf (buffer, sizeof (buffer), format, va);
126 case SWRAP_LOG_ERROR:
128 "SWRAP_ERROR(%d) - %s: %s\n",
129 (int) getpid (), func, buffer);
133 "SWRAP_WARN(%d) - %s: %s\n",
134 (int) getpid (), func, buffer);
136 case SWRAP_LOG_DEBUG:
138 "SWRAP_DEBUG(%d) - %s: %s\n",
139 (int) getpid (), func, buffer);
141 case SWRAP_LOG_TRACE:
143 "SWRAP_TRACE(%d) - %s: %s\n",
144 (int) getpid (), func, buffer);
152 /*********************************************************
153 * SWRAP LOADING LIBC FUNCTIONS
154 *********************************************************/
157 typedef int (*__libc_accept4) (int sockfd,
158 struct sockaddr * addr,
159 socklen_t * addrlen, int flags);
161 typedef int (*__libc_accept) (int sockfd,
162 struct sockaddr * addr, socklen_t * addrlen);
164 typedef int (*__libc_bind) (int sockfd,
165 const struct sockaddr * addr, socklen_t addrlen);
166 typedef int (*__libc_close) (int fd);
167 typedef int (*__libc_connect) (int sockfd,
168 const struct sockaddr * addr,
172 /* TBD: dup and dup2 to be implemented later */
173 typedef int (*__libc_dup) (int fd);
174 typedef int (*__libc_dup2) (int oldfd, int newfd);
177 typedef int (*__libc_fcntl) (int fd, int cmd, ...);
178 typedef FILE *(*__libc_fopen) (const char *name, const char *mode);
180 typedef FILE *(*__libc_fopen64) (const char *name, const char *mode);
183 typedef int (*__libc_eventfd) (int count, int flags);
185 typedef int (*__libc_getpeername) (int sockfd,
186 struct sockaddr * addr,
187 socklen_t * addrlen);
188 typedef int (*__libc_getsockname) (int sockfd,
189 struct sockaddr * addr,
190 socklen_t * addrlen);
191 typedef int (*__libc_getsockopt) (int sockfd,
194 void *optval, socklen_t * optlen);
195 typedef int (*__libc_ioctl) (int d, unsigned long int request, ...);
196 typedef int (*__libc_listen) (int sockfd, int backlog);
197 typedef int (*__libc_open) (const char *pathname, int flags, mode_t mode);
199 typedef int (*__libc_open64) (const char *pathname, int flags, mode_t mode);
200 #endif /* HAVE_OPEN64 */
201 typedef int (*__libc_openat) (int dirfd, const char *path, int flags, ...);
202 typedef int (*__libc_pipe) (int pipefd[2]);
203 typedef int (*__libc_read) (int fd, void *buf, size_t count);
204 typedef ssize_t (*__libc_readv) (int fd, const struct iovec * iov,
206 typedef int (*__libc_recv) (int sockfd, void *buf, size_t len, int flags);
207 typedef int (*__libc_recvfrom) (int sockfd,
211 struct sockaddr * src_addr,
212 socklen_t * addrlen);
213 typedef int (*__libc_recvmsg) (int sockfd, const struct msghdr * msg,
215 typedef int (*__libc_send) (int sockfd, const void *buf, size_t len,
217 typedef int (*__libc_sendmsg) (int sockfd, const struct msghdr * msg,
219 typedef int (*__libc_sendto) (int sockfd, const void *buf, size_t len,
220 int flags, const struct sockaddr * dst_addr,
222 typedef int (*__libc_setsockopt) (int sockfd, int level, int optname,
223 const void *optval, socklen_t optlen);
225 typedef int (*__libc_signalfd) (int fd, const sigset_t * mask, int flags);
227 typedef int (*__libc_socket) (int domain, int type, int protocol);
228 typedef int (*__libc_socketpair) (int domain, int type, int protocol,
230 #ifdef HAVE_TIMERFD_CREATE
231 typedef int (*__libc_timerfd_create) (int clockid, int flags);
233 typedef ssize_t (*__libc_write) (int fd, const void *buf, size_t count);
234 typedef ssize_t (*__libc_writev) (int fd, const struct iovec * iov,
237 typedef int (*__libc_shutdown) (int fd, int how);
239 typedef int (*__libc_select) (int __nfds, fd_set * __restrict __readfds,
240 fd_set * __restrict __writefds,
241 fd_set * __restrict __exceptfds,
242 struct timeval * __restrict __timeout);
245 typedef int (*__libc_pselect) (int __nfds, fd_set * __restrict __readfds,
246 fd_set * __restrict __writefds,
247 fd_set * __restrict __exceptfds,
248 const struct timespec * __restrict __timeout,
249 const __sigset_t * __restrict __sigmask);
252 typedef int (*__libc_epoll_create) (int __size);
254 typedef int (*__libc_epoll_create1) (int __flags);
256 typedef int (*__libc_epoll_ctl) (int __epfd, int __op, int __fd,
257 struct epoll_event * __event);
259 typedef int (*__libc_epoll_wait) (int __epfd, struct epoll_event * __events,
260 int __maxevents, int __timeout);
262 typedef int (*__libc_epoll_pwait) (int __epfd, struct epoll_event * __events,
263 int __maxevents, int __timeout,
264 const __sigset_t * __ss);
267 #define SWRAP_SYMBOL_ENTRY(i) \
273 struct swrap_libc_symbols
276 SWRAP_SYMBOL_ENTRY (accept4);
278 SWRAP_SYMBOL_ENTRY (accept);
280 SWRAP_SYMBOL_ENTRY (bind);
281 SWRAP_SYMBOL_ENTRY (close);
282 SWRAP_SYMBOL_ENTRY (connect);
284 /* TBD: dup and dup2 to be implemented later */
285 SWRAP_SYMBOL_ENTRY (dup);
286 SWRAP_SYMBOL_ENTRY (dup2);
288 SWRAP_SYMBOL_ENTRY (fcntl);
289 SWRAP_SYMBOL_ENTRY (fopen);
291 SWRAP_SYMBOL_ENTRY (fopen64);
294 SWRAP_SYMBOL_ENTRY (eventfd);
296 SWRAP_SYMBOL_ENTRY (getpeername);
297 SWRAP_SYMBOL_ENTRY (getsockname);
298 SWRAP_SYMBOL_ENTRY (getsockopt);
299 SWRAP_SYMBOL_ENTRY (ioctl);
300 SWRAP_SYMBOL_ENTRY (listen);
301 SWRAP_SYMBOL_ENTRY (open);
303 SWRAP_SYMBOL_ENTRY (open64);
305 SWRAP_SYMBOL_ENTRY (openat);
306 SWRAP_SYMBOL_ENTRY (pipe);
307 SWRAP_SYMBOL_ENTRY (read);
308 SWRAP_SYMBOL_ENTRY (readv);
309 SWRAP_SYMBOL_ENTRY (recv);
310 SWRAP_SYMBOL_ENTRY (recvfrom);
311 SWRAP_SYMBOL_ENTRY (recvmsg);
312 SWRAP_SYMBOL_ENTRY (send);
313 SWRAP_SYMBOL_ENTRY (sendmsg);
314 SWRAP_SYMBOL_ENTRY (sendto);
315 SWRAP_SYMBOL_ENTRY (setsockopt);
317 SWRAP_SYMBOL_ENTRY (signalfd);
319 SWRAP_SYMBOL_ENTRY (socket);
320 SWRAP_SYMBOL_ENTRY (socketpair);
321 #ifdef HAVE_TIMERFD_CREATE
322 SWRAP_SYMBOL_ENTRY (timerfd_create);
324 SWRAP_SYMBOL_ENTRY (write);
325 SWRAP_SYMBOL_ENTRY (writev);
327 SWRAP_SYMBOL_ENTRY (shutdown);
328 SWRAP_SYMBOL_ENTRY (select);
330 SWRAP_SYMBOL_ENTRY (pselect);
332 SWRAP_SYMBOL_ENTRY (epoll_create);
333 SWRAP_SYMBOL_ENTRY (epoll_create1);
334 SWRAP_SYMBOL_ENTRY (epoll_ctl);
335 SWRAP_SYMBOL_ENTRY (epoll_wait);
336 SWRAP_SYMBOL_ENTRY (epoll_pwait);
345 struct swrap_libc_symbols symbols;
349 static struct swrap swrap;
351 #define LIBC_NAME "libc.so"
360 swrap_str_lib (enum swrap_lib lib)
368 /* Compiler would warn us about unhandled enum value if we get here */
374 swrap_load_lib_handle (enum swrap_lib lib)
376 int flags = RTLD_LAZY;
381 flags |= RTLD_DEEPBIND;
387 handle = swrap.libc.handle;
391 handle = dlopen (LIBC_SO, flags);
393 swrap.libc.handle = handle;
398 for (i = 10; i >= 0; i--)
400 char soname[256] = { 0 };
402 snprintf (soname, sizeof (soname), "libc.so.%d", i);
403 handle = dlopen (soname, flags);
410 swrap.libc.handle = handle;
417 SWRAP_LOG (SWRAP_LOG_ERROR,
418 "Failed to dlopen library: %s\n", dlerror ());
426 _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
431 handle = swrap_load_lib_handle (lib);
433 func = dlsym (handle, fn_name);
436 SWRAP_LOG (SWRAP_LOG_ERROR,
437 "Failed to find %s: %s\n", fn_name, dlerror ());
441 SWRAP_LOG (SWRAP_LOG_TRACE,
442 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
447 #define swrap_bind_symbol_libc(sym_name) \
448 SWRAP_LOCK(libc_symbol_binding); \
449 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
450 swrap.libc.symbols._libc_##sym_name.obj = \
451 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
453 SWRAP_UNLOCK(libc_symbol_binding)
458 * Functions especially from libc need to be loaded individually, you can't load
459 * all at once or gdb will segfault at startup. The same applies to valgrind and
460 * has probably something todo with with the linker.
461 * So we need load each function at the point it is called the first time.
465 libc_accept4 (int sockfd,
466 struct sockaddr *addr, socklen_t * addrlen, int flags)
468 swrap_bind_symbol_libc (accept4);
470 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
473 #else /* HAVE_ACCEPT4 */
476 libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
478 swrap_bind_symbol_libc (accept);
480 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
482 #endif /* HAVE_ACCEPT4 */
485 libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
487 swrap_bind_symbol_libc (bind);
489 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
495 swrap_bind_symbol_libc (close);
497 return swrap.libc.symbols._libc_close.f (fd);
501 libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
503 swrap_bind_symbol_libc (connect);
505 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
509 /* TBD: dup and dup2 to be implemented later */
513 swrap_bind_symbol_libc (dup);
515 return swrap.libc.symbols._libc_dup.f (fd);
519 libc_dup2 (int oldfd, int newfd)
521 swrap_bind_symbol_libc (dup2);
523 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
529 libc_eventfd (int count, int flags)
531 swrap_bind_symbol_libc (eventfd);
533 return swrap.libc.symbols._libc_eventfd.f (count, flags);
537 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
538 libc_vfcntl (int fd, int cmd, va_list ap)
544 swrap_bind_symbol_libc (fcntl);
546 for (i = 0; i < 4; i++)
548 args[i] = va_arg (ap, long int);
551 rc = swrap.libc.symbols._libc_fcntl.f (fd,
553 args[0], args[1], args[2], args[3]);
559 libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
561 swrap_bind_symbol_libc (getpeername);
563 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
567 libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
569 swrap_bind_symbol_libc (getsockname);
571 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
575 libc_getsockopt (int sockfd,
576 int level, int optname, void *optval, socklen_t * optlen)
578 swrap_bind_symbol_libc (getsockopt);
580 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
582 optname, optval, optlen);
586 libc_listen (int sockfd, int backlog)
588 swrap_bind_symbol_libc (listen);
590 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
594 libc_read (int fd, void *buf, size_t count)
596 swrap_bind_symbol_libc (read);
598 return swrap.libc.symbols._libc_read.f (fd, buf, count);
602 libc_readv (int fd, const struct iovec * iov, int iovcnt)
604 swrap_bind_symbol_libc (readv);
606 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
610 libc_recv (int sockfd, void *buf, size_t len, int flags)
612 swrap_bind_symbol_libc (recv);
614 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
618 libc_recvfrom (int sockfd,
621 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
623 swrap_bind_symbol_libc (recvfrom);
625 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
627 len, flags, src_addr, addrlen);
631 libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
633 swrap_bind_symbol_libc (recvmsg);
635 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
639 libc_send (int sockfd, const void *buf, size_t len, int flags)
641 swrap_bind_symbol_libc (send);
643 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
647 libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
649 swrap_bind_symbol_libc (sendmsg);
651 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
655 libc_sendto (int sockfd,
658 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
660 swrap_bind_symbol_libc (sendto);
662 return swrap.libc.symbols._libc_sendto.f (sockfd,
664 len, flags, dst_addr, addrlen);
668 libc_setsockopt (int sockfd,
669 int level, int optname, const void *optval, socklen_t optlen)
671 swrap_bind_symbol_libc (setsockopt);
673 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
675 optname, optval, optlen);
679 libc_socket (int domain, int type, int protocol)
681 swrap_bind_symbol_libc (socket);
683 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
687 libc_socketpair (int domain, int type, int protocol, int sv[2])
689 swrap_bind_symbol_libc (socketpair);
691 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
695 libc_write (int fd, const void *buf, size_t count)
697 swrap_bind_symbol_libc (write);
699 return swrap.libc.symbols._libc_write.f (fd, buf, count);
703 libc_writev (int fd, const struct iovec * iov, int iovcnt)
705 swrap_bind_symbol_libc (writev);
707 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
711 libc_shutdown (int fd, int how)
713 swrap_bind_symbol_libc (shutdown);
715 return swrap.libc.symbols._libc_shutdown.f (fd, how);
719 libc_select (int __nfds, fd_set * __restrict __readfds,
720 fd_set * __restrict __writefds,
721 fd_set * __restrict __exceptfds,
722 struct timeval *__restrict __timeout)
724 swrap_bind_symbol_libc (select);
726 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
728 __exceptfds, __timeout);
733 libc_pselect (int __nfds, fd_set * __restrict __readfds,
734 fd_set * __restrict __writefds,
735 fd_set * __restrict __exceptfds,
736 const struct timespec *__restrict __timeout,
737 const __sigset_t * __restrict __sigmask)
739 swrap_bind_symbol_libc (pselect);
741 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
744 __timeout, __sigmask);
749 libc_epoll_create (int __size)
751 swrap_bind_symbol_libc (epoll_create);
753 return swrap.libc.symbols._libc_epoll_create.f (__size);
757 libc_epoll_create1 (int __flags)
759 swrap_bind_symbol_libc (epoll_create1);
761 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
765 libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
767 swrap_bind_symbol_libc (epoll_ctl);
769 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
773 libc_epoll_wait (int __epfd, struct epoll_event *__events,
774 int __maxevents, int __timeout)
776 swrap_bind_symbol_libc (epoll_wait);
778 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
779 __maxevents, __timeout);
783 libc_epoll_pwait (int __epfd, struct epoll_event *__events,
784 int __maxevents, int __timeout, const __sigset_t * __ss)
786 swrap_bind_symbol_libc (epoll_pwait);
788 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
789 __maxevents, __timeout,
794 swrap_thread_prepare (void)
800 swrap_thread_parent (void)
806 swrap_thread_child (void)
811 /****************************
813 ***************************/
815 swrap_constructor (void)
818 * If we hold a lock and the application forks, then the child
819 * is not able to unlock the mutex and we are in a deadlock.
820 * This should prevent such deadlocks.
822 pthread_atfork (&swrap_thread_prepare,
823 &swrap_thread_parent, &swrap_thread_child);
826 /****************************
828 ***************************/
831 * This function is called when the library is unloaded and makes sure that
832 * sockets get closed and the unix file for the socket are unlinked.
835 swrap_destructor (void)
837 if (swrap.libc.handle != NULL)
839 dlclose (swrap.libc.handle);
841 if (swrap.libc.socket_handle)
843 dlclose (swrap.libc.socket_handle);
848 * fd.io coding-style-patch-verification: ON
851 * eval: (c-set-style "gnu")