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);
266 typedef int (*__libc_poll) (struct pollfd * __fds, nfds_t __nfds,
270 typedef int (*__libc_ppoll) (struct pollfd * __fds, nfds_t __nfds,
271 const struct timespec * __timeout,
272 const __sigset_t * __ss);
276 #define SWRAP_SYMBOL_ENTRY(i) \
282 struct swrap_libc_symbols
285 SWRAP_SYMBOL_ENTRY (accept4);
287 SWRAP_SYMBOL_ENTRY (accept);
289 SWRAP_SYMBOL_ENTRY (bind);
290 SWRAP_SYMBOL_ENTRY (close);
291 SWRAP_SYMBOL_ENTRY (connect);
293 /* TBD: dup and dup2 to be implemented later */
294 SWRAP_SYMBOL_ENTRY (dup);
295 SWRAP_SYMBOL_ENTRY (dup2);
297 SWRAP_SYMBOL_ENTRY (fcntl);
298 SWRAP_SYMBOL_ENTRY (fopen);
300 SWRAP_SYMBOL_ENTRY (fopen64);
303 SWRAP_SYMBOL_ENTRY (eventfd);
305 SWRAP_SYMBOL_ENTRY (getpeername);
306 SWRAP_SYMBOL_ENTRY (getsockname);
307 SWRAP_SYMBOL_ENTRY (getsockopt);
308 SWRAP_SYMBOL_ENTRY (ioctl);
309 SWRAP_SYMBOL_ENTRY (listen);
310 SWRAP_SYMBOL_ENTRY (open);
312 SWRAP_SYMBOL_ENTRY (open64);
314 SWRAP_SYMBOL_ENTRY (openat);
315 SWRAP_SYMBOL_ENTRY (pipe);
316 SWRAP_SYMBOL_ENTRY (read);
317 SWRAP_SYMBOL_ENTRY (readv);
318 SWRAP_SYMBOL_ENTRY (recv);
319 SWRAP_SYMBOL_ENTRY (recvfrom);
320 SWRAP_SYMBOL_ENTRY (recvmsg);
321 SWRAP_SYMBOL_ENTRY (send);
322 SWRAP_SYMBOL_ENTRY (sendmsg);
323 SWRAP_SYMBOL_ENTRY (sendto);
324 SWRAP_SYMBOL_ENTRY (setsockopt);
326 SWRAP_SYMBOL_ENTRY (signalfd);
328 SWRAP_SYMBOL_ENTRY (socket);
329 SWRAP_SYMBOL_ENTRY (socketpair);
330 #ifdef HAVE_TIMERFD_CREATE
331 SWRAP_SYMBOL_ENTRY (timerfd_create);
333 SWRAP_SYMBOL_ENTRY (write);
334 SWRAP_SYMBOL_ENTRY (writev);
336 SWRAP_SYMBOL_ENTRY (shutdown);
337 SWRAP_SYMBOL_ENTRY (select);
339 SWRAP_SYMBOL_ENTRY (pselect);
341 SWRAP_SYMBOL_ENTRY (epoll_create);
342 SWRAP_SYMBOL_ENTRY (epoll_create1);
343 SWRAP_SYMBOL_ENTRY (epoll_ctl);
344 SWRAP_SYMBOL_ENTRY (epoll_wait);
345 SWRAP_SYMBOL_ENTRY (epoll_pwait);
346 SWRAP_SYMBOL_ENTRY (poll);
348 SWRAP_SYMBOL_ENTRY (ppoll);
358 struct swrap_libc_symbols symbols;
362 static struct swrap swrap;
364 #define LIBC_NAME "libc.so"
373 swrap_str_lib (enum swrap_lib lib)
381 /* Compiler would warn us about unhandled enum value if we get here */
387 swrap_load_lib_handle (enum swrap_lib lib)
389 int flags = RTLD_LAZY;
394 flags |= RTLD_DEEPBIND;
400 handle = swrap.libc.handle;
404 handle = dlopen (LIBC_SO, flags);
406 swrap.libc.handle = handle;
411 for (i = 10; i >= 0; i--)
413 char soname[256] = { 0 };
415 snprintf (soname, sizeof (soname), "libc.so.%d", i);
416 handle = dlopen (soname, flags);
423 swrap.libc.handle = handle;
430 SWRAP_LOG (SWRAP_LOG_ERROR,
431 "Failed to dlopen library: %s\n", dlerror ());
439 _swrap_bind_symbol (enum swrap_lib lib, const char *fn_name)
444 handle = swrap_load_lib_handle (lib);
446 func = dlsym (handle, fn_name);
449 SWRAP_LOG (SWRAP_LOG_ERROR,
450 "Failed to find %s: %s\n", fn_name, dlerror ());
454 SWRAP_LOG (SWRAP_LOG_TRACE,
455 "Loaded %s from %s", fn_name, swrap_str_lib (lib));
460 #define swrap_bind_symbol_libc(sym_name) \
461 SWRAP_LOCK(libc_symbol_binding); \
462 if (swrap.libc.symbols._libc_##sym_name.obj == NULL) { \
463 swrap.libc.symbols._libc_##sym_name.obj = \
464 _swrap_bind_symbol(SWRAP_LIBC, #sym_name); \
466 SWRAP_UNLOCK(libc_symbol_binding)
471 * Functions especially from libc need to be loaded individually, you can't load
472 * all at once or gdb will segfault at startup. The same applies to valgrind and
473 * has probably something todo with with the linker.
474 * So we need load each function at the point it is called the first time.
478 libc_accept4 (int sockfd,
479 struct sockaddr *addr, socklen_t * addrlen, int flags)
481 swrap_bind_symbol_libc (accept4);
483 return swrap.libc.symbols._libc_accept4.f (sockfd, addr, addrlen, flags);
486 #else /* HAVE_ACCEPT4 */
489 libc_accept (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
491 swrap_bind_symbol_libc (accept);
493 return swrap.libc.symbols._libc_accept.f (sockfd, addr, addrlen);
495 #endif /* HAVE_ACCEPT4 */
498 libc_bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
500 swrap_bind_symbol_libc (bind);
502 return swrap.libc.symbols._libc_bind.f (sockfd, addr, addrlen);
508 swrap_bind_symbol_libc (close);
510 return swrap.libc.symbols._libc_close.f (fd);
514 libc_connect (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
516 swrap_bind_symbol_libc (connect);
518 return swrap.libc.symbols._libc_connect.f (sockfd, addr, addrlen);
522 /* TBD: dup and dup2 to be implemented later */
526 swrap_bind_symbol_libc (dup);
528 return swrap.libc.symbols._libc_dup.f (fd);
532 libc_dup2 (int oldfd, int newfd)
534 swrap_bind_symbol_libc (dup2);
536 return swrap.libc.symbols._libc_dup2.f (oldfd, newfd);
542 libc_eventfd (int count, int flags)
544 swrap_bind_symbol_libc (eventfd);
546 return swrap.libc.symbols._libc_eventfd.f (count, flags);
550 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
551 libc_vfcntl (int fd, int cmd, va_list ap)
557 swrap_bind_symbol_libc (fcntl);
559 for (i = 0; i < 4; i++)
561 args[i] = va_arg (ap, long int);
564 rc = swrap.libc.symbols._libc_fcntl.f (fd,
566 args[0], args[1], args[2], args[3]);
571 DO_NOT_SANITIZE_ADDRESS_ATTRIBUTE int
572 libc_vioctl (int fd, int cmd, va_list ap)
578 swrap_bind_symbol_libc (ioctl);
580 for (i = 0; i < 4; i++)
582 args[i] = va_arg (ap, long int);
585 rc = swrap.libc.symbols._libc_ioctl.f (fd,
587 args[0], args[1], args[2], args[3]);
593 libc_getpeername (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
595 swrap_bind_symbol_libc (getpeername);
597 return swrap.libc.symbols._libc_getpeername.f (sockfd, addr, addrlen);
601 libc_getsockname (int sockfd, struct sockaddr *addr, socklen_t * addrlen)
603 swrap_bind_symbol_libc (getsockname);
605 return swrap.libc.symbols._libc_getsockname.f (sockfd, addr, addrlen);
609 libc_getsockopt (int sockfd,
610 int level, int optname, void *optval, socklen_t * optlen)
612 swrap_bind_symbol_libc (getsockopt);
614 return swrap.libc.symbols._libc_getsockopt.f (sockfd,
616 optname, optval, optlen);
620 libc_listen (int sockfd, int backlog)
622 swrap_bind_symbol_libc (listen);
624 return swrap.libc.symbols._libc_listen.f (sockfd, backlog);
628 libc_read (int fd, void *buf, size_t count)
630 swrap_bind_symbol_libc (read);
632 return swrap.libc.symbols._libc_read.f (fd, buf, count);
636 libc_readv (int fd, const struct iovec * iov, int iovcnt)
638 swrap_bind_symbol_libc (readv);
640 return swrap.libc.symbols._libc_readv.f (fd, iov, iovcnt);
644 libc_recv (int sockfd, void *buf, size_t len, int flags)
646 swrap_bind_symbol_libc (recv);
648 return swrap.libc.symbols._libc_recv.f (sockfd, buf, len, flags);
652 libc_recvfrom (int sockfd,
655 int flags, struct sockaddr *src_addr, socklen_t * addrlen)
657 swrap_bind_symbol_libc (recvfrom);
659 return swrap.libc.symbols._libc_recvfrom.f (sockfd,
661 len, flags, src_addr, addrlen);
665 libc_recvmsg (int sockfd, struct msghdr *msg, int flags)
667 swrap_bind_symbol_libc (recvmsg);
669 return swrap.libc.symbols._libc_recvmsg.f (sockfd, msg, flags);
673 libc_send (int sockfd, const void *buf, size_t len, int flags)
675 swrap_bind_symbol_libc (send);
677 return swrap.libc.symbols._libc_send.f (sockfd, buf, len, flags);
681 libc_sendmsg (int sockfd, const struct msghdr *msg, int flags)
683 swrap_bind_symbol_libc (sendmsg);
685 return swrap.libc.symbols._libc_sendmsg.f (sockfd, msg, flags);
689 libc_sendto (int sockfd,
692 int flags, const struct sockaddr *dst_addr, socklen_t addrlen)
694 swrap_bind_symbol_libc (sendto);
696 return swrap.libc.symbols._libc_sendto.f (sockfd,
698 len, flags, dst_addr, addrlen);
702 libc_setsockopt (int sockfd,
703 int level, int optname, const void *optval, socklen_t optlen)
705 swrap_bind_symbol_libc (setsockopt);
707 return swrap.libc.symbols._libc_setsockopt.f (sockfd,
709 optname, optval, optlen);
713 libc_socket (int domain, int type, int protocol)
715 swrap_bind_symbol_libc (socket);
717 return swrap.libc.symbols._libc_socket.f (domain, type, protocol);
721 libc_socketpair (int domain, int type, int protocol, int sv[2])
723 swrap_bind_symbol_libc (socketpair);
725 return swrap.libc.symbols._libc_socketpair.f (domain, type, protocol, sv);
729 libc_write (int fd, const void *buf, size_t count)
731 swrap_bind_symbol_libc (write);
733 return swrap.libc.symbols._libc_write.f (fd, buf, count);
737 libc_writev (int fd, const struct iovec * iov, int iovcnt)
739 swrap_bind_symbol_libc (writev);
741 return swrap.libc.symbols._libc_writev.f (fd, iov, iovcnt);
745 libc_shutdown (int fd, int how)
747 swrap_bind_symbol_libc (shutdown);
749 return swrap.libc.symbols._libc_shutdown.f (fd, how);
753 libc_select (int __nfds, fd_set * __restrict __readfds,
754 fd_set * __restrict __writefds,
755 fd_set * __restrict __exceptfds,
756 struct timeval *__restrict __timeout)
758 swrap_bind_symbol_libc (select);
760 return swrap.libc.symbols._libc_select.f (__nfds, __readfds,
762 __exceptfds, __timeout);
767 libc_pselect (int __nfds, fd_set * __restrict __readfds,
768 fd_set * __restrict __writefds,
769 fd_set * __restrict __exceptfds,
770 const struct timespec *__restrict __timeout,
771 const __sigset_t * __restrict __sigmask)
773 swrap_bind_symbol_libc (pselect);
775 return swrap.libc.symbols._libc_pselect.f (__nfds, __readfds,
778 __timeout, __sigmask);
783 libc_epoll_create (int __size)
785 swrap_bind_symbol_libc (epoll_create);
787 return swrap.libc.symbols._libc_epoll_create.f (__size);
791 libc_epoll_create1 (int __flags)
793 swrap_bind_symbol_libc (epoll_create1);
795 return swrap.libc.symbols._libc_epoll_create1.f (__flags);
799 libc_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event)
801 swrap_bind_symbol_libc (epoll_ctl);
803 return swrap.libc.symbols._libc_epoll_ctl.f (__epfd, __op, __fd, __event);
807 libc_epoll_wait (int __epfd, struct epoll_event *__events,
808 int __maxevents, int __timeout)
810 swrap_bind_symbol_libc (epoll_wait);
812 return swrap.libc.symbols._libc_epoll_wait.f (__epfd, __events,
813 __maxevents, __timeout);
817 libc_epoll_pwait (int __epfd, struct epoll_event *__events,
818 int __maxevents, int __timeout, const __sigset_t * __ss)
820 swrap_bind_symbol_libc (epoll_pwait);
822 return swrap.libc.symbols._libc_epoll_pwait.f (__epfd, __events,
823 __maxevents, __timeout,
828 libc_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout)
830 swrap_bind_symbol_libc (poll);
832 return swrap.libc.symbols._libc_poll.f (__fds, __nfds, __timeout);
837 libc_ppoll (struct pollfd *__fds, nfds_t __nfds,
838 const struct timespec *__timeout, const __sigset_t * __ss)
840 swrap_bind_symbol_libc (ppoll);
842 return swrap.libc.symbols._libc_ppoll.f (__fds, __nfds, __timeout, __ss);
847 swrap_thread_prepare (void)
853 swrap_thread_parent (void)
859 swrap_thread_child (void)
864 /****************************
866 ***************************/
868 swrap_constructor (void)
871 * If we hold a lock and the application forks, then the child
872 * is not able to unlock the mutex and we are in a deadlock.
873 * This should prevent such deadlocks.
875 pthread_atfork (&swrap_thread_prepare,
876 &swrap_thread_parent, &swrap_thread_child);
879 /****************************
881 ***************************/
884 * This function is called when the library is unloaded and makes sure that
885 * sockets get closed and the unix file for the socket are unlinked.
888 swrap_destructor (void)
890 if (swrap.libc.handle != NULL)
892 dlclose (swrap.libc.handle);
894 if (swrap.libc.socket_handle)
896 dlclose (swrap.libc.socket_handle);
901 * fd.io coding-style-patch-verification: ON
904 * eval: (c-set-style "gnu")